2014-11-23 57 views
2

我在表格之一中有與時間表有關的數據,如下所示。如何比較同一表的2條記錄?

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

哪個版本的SQL Server? – 2014-11-23 09:12:07

+0

我正在使用SQL Server 2008版本。 – 2014-11-23 13:29:13

回答

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兩個版本。

+0

嗨,我們正在使用SQL Server 2008.請問您可以共享2008版SQL的解決方案嗎? – 2014-11-23 13:30:34

+0

@PrasadGuduri我現在也更新了2008版本,並對2012+版本做了一些小修改。 – jpw 2014-11-23 18:01:16

+0

太棒了...非常感謝你@Jpw ... !!! – 2014-11-24 04:58:35

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 
+0

http://www.sqlfiddle.com/#!6/37f2a/8 – Vasily 2014-11-23 14:14:57

+0

謝謝@瓦西里...... !!! – 2014-11-24 05:01:07

相關問題