嗨我有这样的数据集:
Date ID
2015-06-17 15:57:00.000 1
NULL 2
NULL 3
NULL 4
NULL 5
NULL 6
2015-06-17 15:58:00.000 7
NULL 8
NULL 9
NULL 10
NULL 11
NULL 12
2015-06-17 17:50:04.000 13
NULL 14
2015-06-17 17:51:00.000 16
NULL 17
2015-06-17 17:52:03.000 19
NULL 20
2015-06-17 17:52:04.000 22
NULL 23
2015-06-17 17:52:04.000 25
NULL 26
2015-06-17 17:52:04.000 28
NULL 29
如您所见,它们按顺序(升序),但许多日期为NULL
我想更新NULL条目以获得最接近的先前日期/时间
所以第2行到第6行应该从第1行和第1行获取日期时间 8到12应该从ID 7等获得日期时间
我确信使用单个更新语句可以轻松实现此目的,但我会画一个空白
答案 0 :(得分:3)
您应该能够使用相关子查询来执行此操作;当我尝试它时,以下查询似乎有效(请参阅下面的小提琴),但请确保备用方便,以防我错了: - )
update t1
set date = (select max(date) from your_table where id <= t1.id and date is not null)
from your_table t1
where t1.date is null
请注意,如果日期不是我认为的顺序日期,这可能会产生一些奇怪的结果。
此外,如果您使用的是版本2012+的SQL Server,那么使用max()
函数作为窗口函数(max(date) over (...)
)是更好的选择。详情见另一个答案。
答案 1 :(得分:2)
你可以在这里有效地使用MAX()OVER()
Update table1
set t1.date = t2.date
From
table1 t1
INNER JOIN (Select id, max(date) over(order by id) date from table1) t2
ON t1.id = t2.id
作为Quassnoi points out,这取决于日期不减少。
Martin Smith contens这个表述更好
WITH CTE AS (
Select *,
max(Date) over(order by ID) AS newdate
from table1)
UPDATE CTE
SET Date = newdate
答案 2 :(得分:1)
2012年及以上:
WITH s AS
(
SELECT id, date,
COALESCE(
LEAD(id) OVER (ORDER BY id),
(
SELECT MAX(id) + 1
FROM t
)
) nid
FROM t
WHERE date IS NOT NULL
)
MERGE
INTO t
USING s
ON t.id > s.id
AND t.id < s.nid
WHEN MATCHED THEN
UPDATE
SET date = s.date
;
这仍然需要读取整个表两次,但是对于每个记录反复来说,它比一个嵌套循环更有效,特别是如果间隙很大。
早期版本:
UPDATE m
FROM mytable m
SET date =
(
SELECT TOP 1
date
FROM mytable mi
WHERE mi.id < m.id
AND mi.date IS NOT NULL
ORDER BY
id DESC
)
WHERE date IS NULL
答案 3 :(得分:0)
Drop Table T1
GO
Create table T1( MyDate DateTime, Id int );
Insert T1 Values
('2015-06-17 15:57:00.000', 1),
(NULL, 2),
(NULL, 3),
(NULL, 4),
(NULL, 5),
(NULL, 6),
('2015-06-17 15:58:00.000', 7),
(NULL, 8),
(NULL, 9),
(NULL, 10),
(NULL, 11),
(NULL, 12),
('2015-06-17 17:50:04.000', 13),
(NULL, 14),
('2015-06-17 17:51:00.000', 16),
(NULL, 17),
('2015-06-17 17:52:03.000', 19),
(NULL, 20),
('2015-06-17 17:52:04.000', 22),
(NULL, 23),
('2015-06-17 17:52:04.000', 25),
(NULL, 26),
('2015-06-17 17:52:04.000', 28),
(NULL, 29) ;
SELECT
A.MyDate,b.LastDate, A.Id
FROM T1 A
CROSS APPLY(
Select Top 1 MyDate as LastDate
From T1
where Id <= A.Id and Mydate is not null
order by id desc
) B