使用SQL Server 2012.每晚数据仓库负载都会填充贷款通过的里程碑日期表。数据如下所示:
CREATE TABLE TestData (LoanKey int, MilestoneCompletedDate datetime, Duration int)
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-16 16:51:56.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-18 15:11:29.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-23 16:21:59.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-28 14:52:00.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-08-26 10:53:37.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-09-19 15:16:38.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-09-20 08:31:38.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-08 15:56:05.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-16 16:11:10.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-10-09 11:20:35.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (2, '2013-09-10 11:15:09.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-06-03 16:22:32.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-06-21 14:46:24.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-08-30 10:03:08.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-08-30 13:55:17.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-09-03 15:28:22.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-09-04 09:30:08.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-09-12 10:44:46.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-09-25 16:06:43.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-06-24 11:59:25.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-09-25 16:06:43.000')
INSERT TestData (LoanKey, MilestoneCompletedDate) VALUES (42, '2013-01-17 15:06:14.000')
加载数据后,我想更新“持续时间”字段。这是一些伪代码:
UPDATE TestData SET Duration = 'Find the DateDiff between the current rows MilestoneCompletedDate and the next greatest milestone completion date for the same loan'
我可以使用PARTITION BY和ORDER BY生成行号:
SELECT
LoanKey,
MilestoneCompletedDate,
ROW_NUMBER() OVER (PARTITION BY LoanKey ORDER BY MilestoneCompletedDate DESC) AS SequenceNumber
FROM
[dbo].[TestData]
有关从何处开始填充持续时间的任何想法?
谢谢你的期待!
答案 0 :(得分:1)
这应该可以完成工作,将HOUR
更改为您喜欢的任何单位:
UPDATE a
SET Duration = DATEDIFF( HOUR
,(SELECT MAX(b.MilestoneCompletedDate)
FROM TestData b
WHERE b.MilestoneCompletedDate < a.MilestoneCompletedDate
AND b.LoanKey = a.LoanKey)
,a.MilestoneCompletedDate )
FROM TestData a
WHERE Duration IS NULL
SQLFiddle目前似乎已被打破,因此无法发布小提琴,但更新后排名前4行(按LoadKey, MilestoneCompletedDate
排序)为:
LoanKey MilestoneCompletedDate Duration
2 2013-08-26 10:53:37.000 NULL
2 2013-09-10 11:15:09.000 361
2 2013-09-19 15:16:38.000 220
2 2013-09-20 08:31:38.000 17
或者,你可以像你想的那样使用ROW_NUMBER
,但它有点混乱。类似的东西:
;WITH cte AS (
SELECT
LoanKey,
MilestoneCompletedDate,
Duration,
ROW_NUMBER() OVER (PARTITION BY LoanKey
ORDER BY MilestoneCompletedDate ASC) AS SeqNum
FROM @TestData
WHERE duration IS NULL
)
UPDATE a
SET Duration = DATEDIFF(HOUR
,b.MilestoneCompletedDate
,a.MilestoneCompletedDate)
FROM cte a
INNER JOIN cte b ON a.LoanKey = b.LoanKey
AND a.SeqNum = b.SeqNum + 1
返回相同的结果集。
答案 1 :(得分:1)
由于您使用的是SQL Server 2012,因此可以使用LEAD
:
在SQL Server 2012中不使用自联接访问同一结果集中后续行的数据。
LEAD
提供对当前行之后的给定物理偏移量的行的访问。
;With leads as (
select *, LEAD(MilestoneCompletedDate) OVER
(PARTITION BY LoanKey
ORDER BY MilestoneCompletedDate) as NextCompletion
from TestData
)
UPDATE leads SET Duration =DATEDIFF(second,MilestoneCompletedDate,NextCompletion)
select * from TestData
产地:
LoanKey MilestoneCompletedDate Duration
----------- ----------------------- -----------
2 2013-10-16 16:51:56.000 166773
2 2013-10-18 15:11:29.000 436230
2 2013-10-23 16:21:59.000 426601
2 2013-10-28 14:52:00.000 NULL
2 2013-08-26 10:53:37.000 1297292
2 2013-09-19 15:16:38.000 62100
2 2013-09-20 08:31:38.000 1581867
2 2013-10-08 15:56:05.000 69870
2 2013-10-16 16:11:10.000 2446
2 2013-10-09 11:20:35.000 622235
2 2013-09-10 11:15:09.000 792089
42 2013-06-03 16:22:32.000 1549432
42 2013-06-21 14:46:24.000 249181
42 2013-08-30 10:03:08.000 13929
42 2013-08-30 13:55:17.000 351185
42 2013-09-03 15:28:22.000 64906
42 2013-09-04 09:30:08.000 695678
42 2013-09-12 10:44:46.000 1142517
42 2013-09-25 16:06:43.000 0
42 2013-06-24 11:59:25.000 5781823
42 2013-09-25 16:06:43.000 NULL
42 2013-01-17 15:06:14.000 11841378
在以前版本的SQL Server上,我已经采用了基于ROW_NUMBER()
的查询,并完成了LEAD
文档中引用的自联接:
;With Ordered as (
SELECT
LoanKey,
MilestoneCompletedDate,
ROW_NUMBER() OVER (PARTITION BY LoanKey
ORDER BY MilestoneCompletedDate DESC) AS SequenceNumber
FROM
[dbo].[TestData]
)
UPDATE o1 SET Duration =
DATEDIFF(second,o1.MilestoneCompletedDate,o2.MilestoneCompletedDate)
FROM Ordered o1
LEFT JOIN Ordered o2
ON o1.LoanKey = o2.LoanKey and o1.SequenceNumber = o2.SequenceNumber - 1