如何找到缺少值的MS SQL?

时间:2019-07-14 10:07:00

标签: sql sql-server

我有一个表格( dataset_final ),其中包含有关一年中特定星期内特定商店中商品销售数量(字段数量)的数据。独特商品约20万,商店约50,期限6年。

dataset_final

    +---------+-------------+---------+----------+----------+
    | year_id | week_number | good_id | store_id | quantity |
    +---------+-------------+---------+----------+----------+
    | 2017    | 37          | 137233  | 9        | 1        |
    +---------+-------------+---------+----------+----------+
    | 2017    | 38          | 137233  | 9        | 4        |
    +---------+-------------+---------+----------+----------+
    | 2017    | 40          | 137233  | 9        | 3        |
    +---------+-------------+---------+----------+----------+
    | 2016    | 35          | 152501  | 23       | 6        |
    +---------+-------------+---------+----------+----------+
    | 2016    | 37          | 152501  | 23       | 3        |
    +---------+-------------+---------+----------+----------+

我希望缺失的值(即当一年中的某个星期没有出售商品和商店的组合时)填充零。例如。

+---------+-------------+---------+----------+----------+
| year_id | week_number | good_id | store_id | quantity |
+---------+-------------+---------+----------+----------+
| 2017    | 37          | 137233  | 9        | 1        |
+---------+-------------+---------+----------+----------+
| 2017    | 38          | 137233  | 9        | 4        |
+---------+-------------+---------+----------+----------+
| 2017    | 40          | 137233  | 9        | 3        |
+---------+-------------+---------+----------+----------+
| 2016    | 35          | 152501  | 23       | 6        |
+---------+-------------+---------+----------+----------+
| 2016    | 37          | 152501  | 23       | 3        |
+---------+-------------+---------+----------+----------+
| 2017    | 39          | 137233  | 9        | 0        |
+---------+-------------+---------+----------+----------+
| 2016    | 36          | 152501  | 23       | 0        |
+---------+-------------+---------+----------+----------+

我想这样做:查找year_id,week_number,good_id,store_id的所有唯一组合,并仅添加 dataset_final 表中没有的那些组合。我的查询:

WITH t1 AS (SELECT  DISTINCT 
       [year_id]
      ,[week_number]
      ,[good_id]
      ,[store_id]

FROM [fs_db].[dbo].[ds_dataset_final]),

t2 AS (SELECT  DISTINCT [year_id], [week_number] FROM [fs_db].[dbo].[ds_dataset_final])

SELECT t2.[year_id], t2.[week_number],  t1.[good_id], t1. [store_id] FROM t1

full join t2 ON t2.[year_id]=t1.[year_id]  AND t2.[week_number]=t2.[week_number]

此查询产生约12亿个唯一组合,这似乎太多了。

此外,我仅从商品销售开始就考虑组合,例如,如果表仅从2017年开始销售特定产品,那么我就不需要填写较早的数据。

2 个答案:

答案 0 :(得分:1)

在没有实际数据库外观的情况下,这是非常伪的SQL,但是,它应该使您走上正确的道路。您需要将dbo.Store之类的对象替换为实际的对象,我建议创建一个适当的日历表:

--This shoudl really be a full calendar table, but we'll making a sample here
CREATE TABLE dbo.Weeks (Year int,
                        Week int);

INSERT INTO dbo.Weeks (Year, Week)
SELECT Y.Year,
       W.Week
FROM (VALUES(2016),(2017),(2018),(2019))Y(Year)
     CROSS APPLY (SELECT TOP 52 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Week
                  FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N1(N),
                       (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N2(N)) W

GO

WITH CTE AS(
    SELECT W.Year,
           W.Week,
           S.StoreID,
           G.GoodsID
    FROM dbo.Weeks W
         CROSS JOIN dbo.Store S
         CROSS JOIN dbo.Goods G
   WHERE EXISTS (SELECT 1
                 FROM dbo.YourTable YT
                 WHERE YT.year_id <= W.Year
                   AND YT.store_id = S.StoreID))
SELECT C.Year,
       C.Week,
       C.StoreID,
       C.GoodsID,
       ISNULL(YT.quantity,0) AS quantity
FROM CTE C
     LEFT JOIN YourTable YT ON C.Year = YT.year_id
                           AND C.Week = YT.week_number
                           AND C.StoreID = YT.store_id
                           AND C.GoodsID = YT.good_id
--WHERE?

答案 1 :(得分:1)

基本思想是使用<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button,Mode=FindAncestor}}" Value="True"> <Setter Property="IsOpen" Value="True"/> </DataTrigger> 概括所有行,然后使用cross join引入值。

假设您在原始表格中具有所有年/周组合,并且在表格中具有所有商品和商店,则可以使用:

left join

每个尺寸可能都有其他来源(例如适当的尺寸表)。如果是这样,请不要使用select vw.year_id, vw.week_number, g.good_id, s.store_id, coalesce(d.quantity, 0) as quantity from (select distinct year_id, week_number from fs_db..ds_dataset_final ) yw cross join (select distinct good_id from fs_db..ds_dataset_final ) g cross join (select distinct store_id from fs_db..ds_dataset_final ) s left join fs_db..ds_dataset_final d on d.year_id = vw.year_id and d.week_number = vw.week_number and d.good_id = g.good_id and d.store_id = s.store_id; ,而要使用参考表。

编辑:

只需在查询中添加最后一行:

select distinct

如果您想要2015、2016、2017和2018年。