Sql Date使用数据库中的可用日期进行分组

时间:2014-06-14 06:40:24

标签: sql-server

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/2014 00:00:00  2
79  6/14/2014 00:00:00  2
80  6/16/2014 00:00:00  2
81  6/17/2014 00:00:00  4
82  6/18/2014 00:00:00  4
83  6/19/2014 00:00:00  4
84  6/20/2014 00:00:00  4
89  6/27/2014 00:00:00  4
90  6/28/2014 00:00:00  4
91  6/29/2014 00:00:00  4
92  6/30/2014 00:00:00  4
93  6/1/2014 00:00:00   4
94  6/2/2014 00:00:00   4
95  6/3/2014 00:00:00   2
96  6/4/2014 00:00:00   2
97  6/5/2014 00:00:00   2
98  6/6/2014 00:00:00   2
99  6/7/2014 00:00:00   2
100 6/21/2014 00:00:00  4
101 6/22/2014 00:00:00  4
102 6/23/2014 00:00:00  4
103 6/24/2014 00:00:00  4
104 7/1/2014 00:00:00   4
105 7/2/2014 00:00:00   4
106 7/3/2014 00:00:00   4
121 7/6/2014 00:00:00   2
122 7/7/2014 00:00:00   2
123 7/8/2014 00:00:00   2

以上记录通过我可以生成以下所有日期的组,如

StartDate - EndDate    EmailID
6/1/2014 -  6/2/2014     4
6/3/2014 -  6/14/2014    2
6/16/2014 - 6/16/2014    2
6/17/2014 - 6/24/2014    4
6/27/2014 - 6/30/2014    4 
7/1/2014  - 7/3/2014     4 


我试图为每个EmailID找到连续的日期块? 任何人都可以解决这个问题 提前谢谢

3 个答案:

答案 0 :(得分:1)

据我了解你的问题,你可以使用以下代码:

select min([Start date - End date]) as StartDate, max([Start date - End date]) as EndSare, EmailID from dbo.T group by EmaiIID

答案 1 :(得分:1)

这是识别按顺序发生的事物组的示例。在这种情况下,这些组按日期排序,您需要连续的日期。

您可以使用两个连续值中的不同值来查找该组。按日期枚举值。然后按日期和emailId枚举值。对于具有相同emailId的连续值,差异是常数。以下是它在您的情况下的工作方式:

select min(TheDate) as StartDate, max(TheDate) as EndDate, emailId
from (select t.*,
             dateadd(day, - row_number() over (order by TheDate), theDate) as grp
      from table t
     ) t
group by grp, emailId;

答案 2 :(得分:1)

这将为您解决问题。首先确定范围开始,然后范围结束,同时设置范围标识。最后合并范围的开始和结束集。

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

结果并不像你想象的那样,但是我可以更正。