我有这个SQL表,如下所示:
customer date number
--------- ---- ------
A 1 3
A 2 NULL
A 3 5
A 4 NULL
A 5 6
B 1 NULL
B 2 NULL
B 3 10
根据客户的说法,我希望添加一个额外的列number_NEW,它用下一个已知的按时间顺序排列的已知数字(由日期确定)替换NULL中的NULL(如果这是null):
customer date number number_NEW
--------- ---- ------ ----------
A 1 3 3
A 2 NULL 5
A 3 5 5
A 4 NULL 6
A 5 6 6
B 1 NULL 10
B 2 NULL 10
B 3 10 10
我如何在SQL中解决这个问题?
非常感谢!
答案 0 :(得分:1)
您可以使用APPLY:
SELECT
*,
Number_NEW = ISNULL(t.Number, x.Number)
FROM Test t
OUTER APPLY(
SELECT TOP 1 Number
FROM Test
WHERE
Customer = t.Customer
AND Date > t.Date
AND Number IS NOT NULL
ORDER BY Date
)x
ORDER BY t.Customer, t.Date
答案 1 :(得分:0)
您的样本数据未达标。
[date]列不清楚。为了安全起见,我使用了row_number,我认为这是必需的。
此外,我认为您的问题已经解决。我已经使用动态LEAD()的sql 2012编写了此脚本。
它不仅提供正确的输出,还描绘了LEAD()的动态使用。
Declare @t table(customer varchar(20),[date] int, number int)
insert into @t values
('A', 1,3 )
,('A', 2, NULL)
,('A', 3, 5 )
,('A', 4, NULL )
,('A', 5, 6)
,('B', 1, NULL)
,('B', 2, NULL)
,('B', 3, 10)
;WITH CTE
AS (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY customer ORDER BY [DATE]
) RN
FROM @T
)
--SELECT * FROM CTE
SELECT *
,IIF(number IS NULL, LEAD(number, (
SELECT TOP 1 RN - A.RN
FROM CTE
WHERE customer = a.customer
AND RN > a.RN
AND number IS NOT NULL
ORDER BY RN
), number) OVER (
ORDER BY customer
,[date]
), number) number_NEW
FROM CTE A
答案 2 :(得分:0)
alter table T add number_NEW int null;
update T /* substitute table name here -- I realize that SQL Server allows aliases */
set number_NEW =
case
when number is null
then (
select min(t2.number) /* do date and number always increase together? */
from T as t2
/* substitute full table name here as well */
where t2.customer = T.customer and t2.date > T."date"
)
else number
end
);
alter table T alter column number_NEW int not null;