我有一个表中的时间表相关数据如下。
ScheduledID StartTime EndTime ModifiedTimeStamp
1 10 AM 6 PM 01-01-2014 09:00
1 11 AM 6 PM 01-01-2014 09:30
1 11 AM 7 PM 01-01-2014 10:00
1 10 AM 6 PM 01-01-2014 10:30
1 11 AM 8 PM 01-01-2014 11:00
如上所述,计划开始和结束时间会多次修改。
我需要显示以下数据。
ScheduledID StartTime EndTime ModifiedTimeStamp Action Type
1 10 AM 6 PM 01-01-2014 09:00 Schedule Created
1 11 AM 6 PM 01-01-2014 09:30 Start Time Modified from 10AM to 11AM
1 11 AM 7 PM 01-01-2014 10:00 End Time Modified from 6PM to 7PM
1 10 AM 6 PM 01-01-2014 10:30 Start Time Modified from 11AM to 10AM, End Time Modified from 7PM to 6PM
1 11 AM 8 PM 01-01-2014 11:00 Current Schedule
请指导我如何实现这一目标?
谢谢。
答案 0 :(得分:4)
如果您使用的是SQL Server 2012或更高版本,则可以使用LAG()
和LEAD()
窗口函数来访问上一行和下一行,并使用如下所示的查询来呈现您想要的结果:
-- 2012+ version
SELECT
ScheduledID, StartTime, EndTime, ModifiedTimeStamp,
CASE
WHEN prevts IS NULL THEN 'Schedule created'
WHEN prevStartTime <> StartTime AND prevEndTime = EndTime AND nextts IS NOT NULL
THEN CONCAT('Start Time Modified FROM ', prevStartTime, ' to ', StartTime)
WHEN prevStartTime <> StartTime AND prevEndTime <> EndTime AND nextts IS NOT NULL
THEN CONCAT('Start Time Modified FROM ', prevStartTime, ' to ', StartTime,
', End Time Modified FROM ', prevEndTime, ' to ', EndTime)
WHEN prevStartTime = StartTime AND prevEndTime <> EndTime AND nextts IS NOT NULL
THEN CONCAT('End Time Modified FROM ', prevEndTime, ' to ', EndTime)
WHEN nextts IS NULL
THEN 'Current Schedule'
END as 'Action Type'
FROM (
SELECT
ScheduledID,
prevStartTime = LAG(StartTime) OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp),
StartTime,
nextStartTime = LEAD(StartTime) OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp),
prevEndTime = LAG(EndTime) OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp),
EndTime,
nextEndTime = LEAD(EndTime) OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp),
prevts = LAG(ModifiedTimeStamp) OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp),
ModifiedTimeStamp,
nextts = LEAD(ModifiedTimeStamp) OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp)
FROM schedules
) a
如果您使用的是早于2012的版本,则可以使用ROW_NUMBER()
功能和自加入,如下所示:
-- 2008 version
SELECT
curr.ScheduledID, curr.StartTime, curr.EndTime, curr.ModifiedTimeStamp,
CASE
WHEN prev.rn IS NULL THEN 'Schedule created'
WHEN prev.StartTime <> curr.StartTime AND prev.EndTime = curr.EndTime
THEN 'Start Time Modified FROM ' + prev.StartTime + ' to ' + curr.StartTime
WHEN prev.StartTime <> curr.StartTime AND prev.EndTime <> curr.EndTime AND next.rn IS NOT NULL
THEN 'Start Time Modified FROM ' + prev.StartTime + ' to ' + curr.StartTime
+ ', End Time Modified FROM ' + prev.EndTime + ' to ' + curr.EndTime
WHEN prev.EndTime <> curr.EndTime AND next.rn IS NOT NULL
THEN 'End Time Modified FROM ' + prev.EndTime + ' to ' + curr.EndTime
WHEN next.rn IS NULL THEN 'Current schedule'
END as 'Action Type'
FROM (
SELECT ScheduledID, StartTime, EndTime, ModifiedTimeStamp, ROW_NUMBER() OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp) rn
FROM schedules) curr
LEFT JOIN (
SELECT ScheduledID, StartTime, EndTime, ModifiedTimeStamp, ROW_NUMBER() OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp) rn
FROM schedules
) prev on curr.rn = prev.rn + 1 AND prev.ScheduledID = curr.ScheduledID
LEFT JOIN (
SELECT ScheduledID, StartTime, EndTime, ModifiedTimeStamp, ROW_NUMBER() OVER (PARTITION by ScheduledID ORDER BY ModifiedTimeStamp) rn
FROM schedules
) next on curr.rn = next.rn - 1 AND curr.ScheduledID = next.ScheduledID
ORDER BY curr.rn
Sample SQL Fiddle这两个版本。
答案 1 :(得分:2)
;
WITH cte
AS ( SELECT ROW_NUMBER() OVER ( PARTITION BY ScheduledID ORDER BY modifiedtimestamp ) AS RN ,
ScheduledID ,
StartTime ,
EndTime ,
ModifiedTimeStamp
FROM schedules
),
laglead2008
AS ( SELECT a.ScheduledID ,
b.StartTime AS prevStartTime ,
a.StartTime ,
c.StartTime AS nextStartTime ,
b.EndTime AS prevEndtime ,
a.EndTime ,
c.EndTime AS nextEndTime ,
b.modifiedtimestamp AS prevts ,
a.ModifiedTimeStamp ,
c.modifiedtimestamp AS nextts
FROM cte AS a
LEFT JOIN cte AS b ON ( a.RN - 1 ) = b.RN
AND b.ScheduledID = a.ScheduledID
LEFT JOIN cte AS c ON ( a.RN + 1 ) = c.RN
AND a.ScheduledID = b.ScheduledID
)
SELECT ScheduledID ,
StartTime ,
EndTime ,
ModifiedTimeStamp ,
CASE WHEN prevts IS NULL THEN 'Schedule created'
WHEN prevStartTime <> StartTime
AND prevEndtime = EndTime
AND nextts IS NOT NULL
THEN 'Start Time Modified from ' + prevStartTime + ' to '
+ StartTime
WHEN prevStartTime <> StartTime
AND prevEndtime <> EndTime
AND nextts IS NOT NULL
THEN 'Start Time Modified from ' + prevStartTime + ' to '
+ StartTime + ', End Time Modified from ' + prevEndtime
+ ' to ' + EndTime
WHEN prevStartTime = StartTime
AND prevEndtime <> EndTime
AND nextts IS NOT NULL
THEN 'End Time Modified from ' + prevEndtime + ' to '
+ EndTime
WHEN nextts IS NULL THEN 'Current Schedule'
END AS 'Action Type'
FROM laglead2008