如何在每组的前一行填充NULL
值?
说出类似的话,
+--------+---------+--------+
| Date | Product | Amount |
+ + + +
| 7/1/15 | Prod1 | 5 |
| 7/1/15 | Prod2 | 7 |
| 7/1/15 | Prod3 | 9 |
| 8/1/15 | Prod1 | NULL |
| 8/1/15 | Prod2 | 8 |
| 8/1/15 | Prod3 | NULL |
| 9/1/15 | Prod1 | 1 |
| 9/1/15 | Prod2 | NULL |
| 9/1/15 | Prod3 | NULL |
| 10/1/15| Prod1 | NULL |
+--------+---------+--------+
实现这样的目标:
+--------+---------+--------+
| Date | Product | Amount |
+ + + +
| 7/1/15 | Prod1 | 5 |
| 7/1/15 | Prod2 | 7 |
| 7/1/15 | Prod3 | 9 |
| 8/1/15 | Prod1 | 5 |
| 8/1/15 | Prod2 | 8 |
| 8/1/15 | Prod3 | 9 |
| 9/1/15 | Prod1 | 1 |
| 9/1/15 | Prod2 | 8 |
| 9/1/15 | Prod3 | 9 |
| 10/1/15| Prod1 | 1 |
+--------+---------+--------+
这有意义吗?我不知道从哪里开始。任何帮助将非常感激。谢谢!
修改
规则:
Amount
列为NULL
,则应使用同一Amount
类别中的Amount
的{{1}}填充,而不是Product
1}}。比如说,上面是一个示例数据。
这一行
NULL
它的数量应该填充Date | Product | Amount
8/1/15 | Prod1 | NULL
,因为它应该在相同的5
类别中获取它之前的值。
答案 0 :(得分:2)
您可以使用ISNULL
(或COALESCE
)和相关子查询:
SELECT t.Date, t.Product,
Amount = ISNULL(t.Amount,
(SELECT TOP 1 Amount
FROM dbo.TableName t2
WHERE t2.Product = t.Product
AND t2.Amount IS NOT NULL
AND t2.Date <= t.Date
ORDER BY t2.Date DESC))
FROM dbo.TableName t
Demo 包含您的样本数据。
我更喜欢ISNULL
而不是CAOLESCE
,因为后者will be translated to a CASE
that is executed twice。您可以详细了解该问题at MS-Connect。
答案 1 :(得分:0)
您需要这样的查询:
;WITH t AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY [Date]) rn
FROM yourTable)
, tt AS (
SELECT t1.[Date], t1.Product, t1.Amount, MAX(CASE WHEN t2.Amount IS NOT NULL THEN t2.rn END) AS LastSeq
FROM t t1
LEFT JOIN
t t2 ON t1.Product = t2.Product AND t2.rn <= t1.rn
GROUP BY t1.[Date], t1.Product, t1.Amount)
SELECT tt.[Date], tt.Product, ISNULL(tt.Amount, t.Amount) As Amount
FROM tt
JOIN t ON tt.Product = t.Product AND tt.LastSeq = t.rn
ORDER BY tt.[Date], tt.Product
答案 2 :(得分:0)
我将建议cross apply
:
update table t cross apply
(select top 1 t2.*
from table t2
where t2.product = t.product and
t2.date < t.date and
t2.amount is not null
order by t2.date desc
) toupdate
set amount = toupdate.amount
where t.amount is null;
编辑:
如果您知道NULL
s字符串永远不会太多,您可以执行以下操作:
update table t
set product = coalesce(lag(amount) over (partition by product order by date),
lag(amount, 2) over (partition by product order by date),
lag(amount, 3) over (partition by product order by date)
)
where product is null;
或者,或者,只需运行:
update table t
set product = lag(amount) over (partition by product order by date)
where product is null;
直到没有行改变。