如何替换缺少值的MS SQL?

时间:2019-07-22 17:19:45

标签: sql sql-server

有一张关于商店中商品销售的表格(MS SQL 2017),有些记录没有价格。

+---------+-------------+---------+----------+-------+
| year_id | week_number | good_id | store_id | price |
+---------+-------------+---------+----------+-------+
| 2019    | 6           | 140629  | 2        | 199   |
+---------+-------------+---------+----------+-------+
| 2019    | 8           | 140629  | 2        | NULL  |
+---------+-------------+---------+----------+-------+
| 2017    | 40          | 137233  | 9        | 278   |
+---------+-------------+---------+----------+-------+
| 2017    | 35          | 137233  | 9        | NULL  |
+---------+-------------+---------+----------+-------+
| 2017    | 37          | 137233  | 9        | NULL  |
+---------+-------------+---------+----------+-------+

我们要根据以下方案替换缺失值:将价格值设置为与同一家商店(store_id)中此编号( good_id )的商品相同,但已出售尽可能在最接近缺失值日期的日期,例如:

+---------+-------------+---------+----------+-------+
| year_id | week_number | good_id | store_id | price |
+---------+-------------+---------+----------+-------+
| 2019    | 6           | 140629  | 2        | 199   |
+---------+-------------+---------+----------+-------+
| 2019    | 8           | 140629  | 2        | 199   |
+---------+-------------+---------+----------+-------+
| 2017    | 40          | 137233  | 9        | 278   |
+---------+-------------+---------+----------+-------+
| 2017    | 35          | 137233  | 9        | 278   |
+---------+-------------+---------+----------+-------+
| 2017    | 37          | 137233  | 9        | 278   |
+---------+-------------+---------+----------+-------+

到目前为止已经做了类似的事情,但是该查询包含互斥条件,因此它不会影响行:

UPDATE dataset
SET price = p.price
FROM dataset AS p
WHERE good_id = p.good_id
AND store_id = p.store_id
AND price IS NULL
AND p.price IS NOT NULL;
GO

1 个答案:

答案 0 :(得分:1)

您可以使用apply。如果所有年份都有52周,则此方法有效:

update d
    set price = d2.price
    from dataset d cross apply
         (select top (1) d2.*
          from dataset d2
          where d2.good_id = d.good_id and
                d2.store_id = d.store_id and
                d2.price is not null
          order by abs( (d2.year_id * 52 + d2.week_id) - (d.year_id * 52 + d.week_id) )
         ) d2
    where d.price is null;

唯一的问题是当比较超过年份边界并且上一年有53周时。根据您定义年份的方式,您可以将年/周组合转换为日期,并使用直接的日期比较来计算差异。