2012-11-19 76 views
2

類似的問題:Crosstabbing rows based on sequence islands in a list of times交叉SQL行與小數列的SUM

看看下面的示例數據:

Employ  Date   Duration 
0000001 2012-11-12 9.00 
0000001 2012-11-13 9.00 
0000001 2012-11-14 9.00 
0000001 2012-11-16 9.00 
0000001 2012-11-17 9.00 
0000002 2012-11-04 9.00 
0000002 2012-11-05 9.00 
0000002 2012-11-06 9.00 
0000003 2012-11-01 9.00 
0000004 2012-11-02 6.50 

我試圖改變這個如下:

Employ  Start Date End Date  Days TotalDuration 
0000001 2012-11-12 2012-11-14 3  27 
0000001 2012-11-16 2012-11-17 2  18 
0000002 2012-11-04 2012-11-06 3  27 
0000003 2012-11-01 2012-11-01 1  9.00 
0000004 2012-11-02 2012-11-02 1  6.50 

使用上面鏈接的問題,我試過這樣做,如下所示:

WITH ExampleData ([DET_NUMBERA], [Date], [Duration]) 
      AS ( 
       SELECT '0000001' AS [DET_NUMBERA], CONVERT(DATE, '12/11/2012', 103) AS [Date], 9.00 AS [Duration] 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '13/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '14/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '16/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '17/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000002', CONVERT(DATE, '04/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000002', CONVERT(DATE, '05/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000002', CONVERT(DATE, '06/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000003', CONVERT(DATE, '01/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000004', CONVERT(DATE, '02/11/2012', 103), 6.5 
      ), 
     CrossTabPrep 
      AS (SELECT [DET_NUMBERA] , 
         [Date] , 
         [Duration] , 
         CONVERT(INT, CONVERT(VARCHAR(10), GETDATE(), 112)) - ROW_NUMBER() OVER (PARTITION BY [DET_NUMBERA] ORDER BY [Date]) AS [Grp] 
       FROM  ExampleData 
      ), 
     FinalRender ([DET_NUMBERA], [Start Date], [End Date], [Days], [Duration]) 
      AS (SELECT [DET_NUMBERA] , 
         MIN([Date]) AS [Start Date] , 
         MAX([Date]) AS [End Date] , 
         ISNULL(DATEDIFF(DAY, MIN([Date]), MAX([Date])), 0) AS [Days] , 
         SUM([Duration]) AS [Duration] 
       FROM  CrossTabPrep 
       GROUP BY [DET_NUMBERA] , 
         [Grp] 
      ) 
    SELECT * 
    FROM FinalRender 
    ORDER BY [DET_NUMBERA] 

但是它的工作並不完美 - 我的某處出了問題 - 我如何調整這個SQL來進行如上所述的轉換。

回答

0

Doh!我在我的Grp標識符中使用了getDate(),而不是[日期]列!

修訂如下 - 工作正常&處理中斷:

WITH ExampleData ([DET_NUMBERA], [Date], [Duration]) 
      AS ( 
       SELECT '0000001' AS [DET_NUMBERA], CONVERT(DATE, '12/11/2012', 103) AS [Date], 9.00 AS [Duration] 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '13/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '14/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '16/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000001', CONVERT(DATE, '17/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000002', CONVERT(DATE, '04/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000002', CONVERT(DATE, '05/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000002', CONVERT(DATE, '06/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000003', CONVERT(DATE, '01/11/2012', 103), 9.00 
       UNION ALL 
       SELECT '0000004', CONVERT(DATE, '02/11/2012', 103), 6.5 
      ), 
     CrossTabPrep 
      AS (SELECT [DET_NUMBERA] , 
         [Date] , 
         [Duration] , 
         CONVERT(INT, CONVERT(VARCHAR(10), [Date], 112)) - ROW_NUMBER() OVER (PARTITION BY [DET_NUMBERA] ORDER BY [Date]) AS [Grp] 
       FROM  ExampleData 
      ), 
     FinalRender ([DET_NUMBERA], [Start Date], [End Date], [Days], [Duration]) 
      AS (SELECT [DET_NUMBERA] , 
         MIN([Date]) AS [Start Date] , 
         MAX([Date]) AS [End Date] , 
         ISNULL(DATEDIFF(DAY, MIN([Date]), MAX([Date])), 0) + 1 AS [Days] , 
         SUM([Duration]) AS [Duration] 
       FROM  CrossTabPrep 
       GROUP BY [DET_NUMBERA] , 
         [Grp] 
      ) 
    SELECT * 
    FROM FinalRender 
    ORDER BY [DET_NUMBERA] 
0

部分問題出在FinalRender[Grp]字段上有GROUP BY。這使得您的總數值爲DISTINCT的值爲:

WITH ExampleData ([DET_NUMBERA], [Date], [Duration]) 
    AS ( 
     SELECT '0000001' AS [DET_NUMBERA], CONVERT(DATE, '12/11/2012', 103) AS [Date], 9.00 AS [Duration] 
     UNION ALL 
     SELECT '0000001', CONVERT(DATE, '13/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000001', CONVERT(DATE, '14/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000001', CONVERT(DATE, '15/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000001', CONVERT(DATE, '16/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000002', CONVERT(DATE, '04/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000002', CONVERT(DATE, '05/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000002', CONVERT(DATE, '06/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000003', CONVERT(DATE, '01/11/2012', 103), 9.00 
     UNION ALL 
     SELECT '0000004', CONVERT(DATE, '02/11/2012', 103), 6.5 
    ), 
CrossTabPrep 
    AS (SELECT [DET_NUMBERA] , 
       [Date] , 
       [Duration] , 
       CONVERT(INT, CONVERT(VARCHAR(10), GETDATE(), 112)) - ROW_NUMBER() OVER (PARTITION BY [DET_NUMBERA] ORDER BY [Date]) AS [Grp] 
     FROM  ExampleData 
    ), 
FinalRender ([DET_NUMBERA], [Start Date], [End Date], [Days], [Duration]) 
    AS (SELECT [DET_NUMBERA] , 
       MIN([Date]) AS [Start Date] , 
       MAX([Date]) AS [End Date] , 
       ISNULL(DATEDIFF(DAY, MIN([Date]), MAX([Date])), 0) AS [Days] , 
       SUM([Duration]) AS [Duration] 
     FROM  CrossTabPrep 
     GROUP BY [DET_NUMBERA] 
    ) 
SELECT * 
FROM FinalRender 
ORDER BY [DET_NUMBERA] 
+0

乾杯您的幫助,還是雖然不是很正確,而沒有GROUP BY [GRP] 0000001被歸類爲1個島12日 - 16日,這ISN不正確,應該是兩個不同的行,從12 - 14 1和16 - 17(我編輯我的問題,以演示這個問題 - 注意缺失的15日應該拆分000001)。 – HeavenCore