按重叠日期进行 SQL 分区

标签 sql sql-server t-sql

我有如下表,如果日期基于相同的成员 ID 重叠,我想对表进行分区。我使用以下代码,但它仅根据成员 ID 进行分区,但不根据重叠日期进行分区。如何包含也考虑重叠日期的分区?

ID MemberID StartDate   EndDate      
1  2        2015-01-01  2015-02-28
2  2        2015-02-02  2015-02-03 
3  2        2015-05-01  2015-05-20 
4  1        2015-02-01  2015-02-28 
5  2        2015-02-01  2015-03-01 


SELECT *
,ROW_NUMBER() OVER(PARTITION BY MEMBERID ORDER BY ID) AS GROUPID
FROM TABLENAME AS A


ID MemberID StartDate   EndDate      
1  2        2015-01-01  2015-02-28
2  2        2015-02-01  2015-02-03 
3  2        2015-05-01  2015-05-20 
4  1        2015-02-01  2015-02-28 
5  2        2015-02-01  2015-03-01 

当前输出:

ID MemberID StartDate   EndDate      GROUPID
4  1        2015-02-01  2015-02-28   1
1  2        2015-01-01  2015-02-28   1
2  2        2015-02-02  2015-02-03   2
3  2        2015-05-01  2015-05-20   3
5  2        2015-02-01  2015-03-01   4

预期输出:

ID MemberID StartDate   EndDate      GROUPID
4  1        2015-02-01  2015-02-28   1
1  2        2015-01-01  2015-02-28   1
2  2        2015-02-02  2015-02-03   2
5  2        2015-02-01  2015-02-28   3
3  2        2015-05-01  2015-05-20   1

最佳答案

此查询给出正确的输出:

WITH ord as (
    SELECT ID, MemberID
        , StartDate, EndDate
        , n = ROW_NUMBER() over(partition by [MemberID] order by [StartDate], [EndDate])
    FROM @data d1
), first as (
    SELECT o1.ID, o1.MemberID
        , o1.n
    FROM ord o1
    INNER JOIN ord o2 ON o1.MemberID = o2.MemberID AND o2.n+1 = o1.n AND o1.StartDate > o2.EndDate
), groups as (
    SELECT o.ID, o.MemberID
        , p = ROW_NUMBER() over(partition by o.MemberID, MIN(coalesce(f.n, 1)) ORDER BY o.ID)
    FROM ord o
    LEFT JOIN first f ON o.MemberID = f.MemberID AND o.n < f.n
    GROUP BY o.ID, o.MemberID
)
SELECT g.ID, g.MemberID, d.StartDate, d.EndDate, GROUPID = g.p
FROM groups g
INNER JOIN @data d ON g.ID = d.ID

请注意,必须使用更多数据对其进行测试。

输出:

ID  MemberID    StartDate   EndDate     GROUPID
4   1           2015-02-01  2015-02-28  1
3   2           2015-05-01  2015-05-20  1
1   2           2015-01-01  2015-02-28  1
2   2           2015-02-02  2015-02-03  2
5   2           2015-02-01  2015-03-01  3

您的数据:

declare @data table([ID] int, [MemberID] int, [StartDate] date, [EndDate] date);
Insert into @data([ID], [MemberID], [StartDate], [EndDate])
VALUES
    (1, 2, '2015-01-01', '2015-02-28'),
    (2, 2, '2015-02-02', '2015-02-03'),
    (3, 2, '2015-05-01', '2015-05-20'),
    (4, 1, '2015-02-01', '2015-02-28'),
    (5, 2, '2015-02-01', '2015-03-01')
;

关于按重叠日期进行 SQL 分区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34015215/

相关文章:

php - MySQL 中两列的不同值

sql - "WARNING: did not see LOP_CKPT_END"消息在 SQL Server 2005 中意味着什么?

sql-server - 从存储过程插入不同的列

sql-server - 如何选择两个字符之间的数据

java - jOOQ - 基于唯一键(非主键)更新记录

mysql - 将所有查询结果分为 2 个类别

mysql - 需要写MySQL case语句

sql-server - SQL Server 中的 ANSI_NULLS 标志?

sql - 如何对列中包含可变数据的表进行数据透视表

sql - 如何优化此查询(OR 内部 AND 验证)?