Sql Date Grouping with avaliable dates in database

后端 未结 3 436
野性不改
野性不改 2021-01-17 05:17
ID         dateandtime  EmailID
73  6/8/2014 00:00:00   2
74  6/9/2014 00:00:00   2
75  6/10/2014 00:00:00  2
76  6/11/2014 00:00:00  2
77  6/12/2014 00:00:00  2
78  6/13         


        
3条回答
  •  时光取名叫无心
    2021-01-17 05:41

    This will do the trick for you. First identify the range starts and then the range ends and at the same time set a range identity. Last merge the range start and end sets.

    DECLARE @Data TABLE (
        [ID] INT,
        [Date] DATE,
        [EmailID] INT
    )
    INSERT INTO
        @Data
    VALUES
        (  73, '2014-06-08', 2 ),
        (  74, '2014-06-09', 2 ),
        (  75, '2014-06-10', 2 ),
        (  76, '2014-06-11', 2 ),
        (  77, '2014-06-12', 2 ),
        (  78, '2014-06-13', 2 ),
        (  79, '2014-06-14', 2 ),
        (  80, '2014-06-16', 2 ),
        (  81, '2014-06-17', 4 ),
        (  82, '2014-06-18', 4 ),
        (  83, '2014-06-19', 4 ),
        (  84, '2014-06-20', 4 ),
        (  89, '2014-06-27', 4 ),
        (  90, '2014-06-28', 4 ),
        (  91, '2014-06-29', 4 ),
        (  92, '2014-06-30', 4 ),
        (  93, '2014-06-01', 4 ),
        (  94, '2014-06-02', 4 ),
        (  95, '2014-06-03', 2 ),
        (  96, '2014-06-04', 2 ),
        (  97, '2014-06-05', 2 ),
        (  98, '2014-06-06', 2 ),
        (  99, '2014-06-07', 2 ),
        ( 100, '2014-06-21', 4 ),
        ( 101, '2014-06-22', 4 ),
        ( 102, '2014-06-23', 4 ),
        ( 103, '2014-06-24', 4 ),
        ( 104, '2014-07-01', 4 ),
        ( 105, '2014-07-02', 4 ),
        ( 106, '2014-07-03', 4 ),
        ( 121, '2014-07-06', 2 ),
        ( 122, '2014-07-07', 2 ),
        ( 123, '2014-07-08', 2 );
    
    WITH RangeStart AS (
        SELECT
            l.[Date] AS Start,
            l.EmailID AS EmailId,
            ROW_NUMBER() OVER (ORDER BY l.[Date]) AS [RangeId]
        FROM
            @Data as l
            LEFT OUTER JOIN @Data as r on r.[Date] = DATEADD(day, -1, l.[Date])
                AND r.EmailID = l.EmailID
        WHERE
            r.[Date] IS NULL
    ), RangeEnd AS (
        SELECT
            l.[Date] AS [End],
            l.EmailID AS EmailId,
            ROW_NUMBER() OVER (ORDER BY l.[Date]) AS [RangeId]
        FROM
            @Data as l
            LEFT OUTER JOIN @Data as r on r.[Date] = DATEADD(day, +1, l.[Date])
                AND r.EmailID = l.EmailID
        WHERE
            r.[Date] IS NULL
    )
    SELECT
        RangeStart.Start,
        RangeEnd.[End],
        RangeStart.EmailId
    FROM
        RangeStart
        JOIN RangeEnd ON RangeEnd.RangeId = RangeStart.RangeId
    

    The result is not as you might expect, however from what I can se correct.

提交回复
热议问题