2

类似问题:基于时间列表中的序列岛对行进行交叉表

以以下示例数据为例:

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 以进行如上所述的转换。

4

2 回答 2

0

部分问题在于FinalRender你有一个GROUP BY[Grp]场上。这使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]
于 2012-11-19T15:23:37.717 回答
0

嗬!我getDate()在我的 Grp Identifier 中使用而不是 [Date] 列!

修改如下 - 工作正常并处理中断:

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]
于 2012-11-19T15:51:53.237 回答