【问题标题】:SQL Server Extract overlapping date ranges (return dates that cross other dates)SQL Server 提取重叠日期范围(返回与其他日期交叉的日期)
【发布时间】:2014-07-21 19:31:04
【问题描述】:

我将如何从下表中提取重叠日期?

ID  Name        StartDate   EndDate     Type
==============================================================
1   John Smith  01/01/2014  31/01/2014  A
2   John Smith  20/01/2014  20/02/2014  B
3   John Smith  01/03/2014  28/03/2014  A
4   John Smith  18/03/2014  24/03/2014  B
5   John Smith  01/07/2014  31/07/2014  A
6   John Smith  15/07/2014  31/07/2014  B
7   John Smith  25/07/2014  25/08/2014  C

根据 John Smith 的第一个示例,日期 01/01/2014 到 31/01/2014 与 20/01/2014 到 20/02/2014 重叠,所以我预计只是重叠的时期,即 20 /01/2014 至 31/01/2014。

最终的结果是:

ID  Name        StartDate   EndDate
==================================================
8   John Smith  20/01/2014  31/01/2014
9   John Smith  18/03/2014  24/03/2014
10  John Smith  15/07/2014  31/07/2014
11  John Smith  25/07/2014  31/07/2014

2014 年 8 月 10 日需要帮助

除了上述请求之外,我还在寻求有关如何获得以下结果的帮助或指导,这些结果应包括重叠的日期和不重叠的日期。 ID 列无关紧要。

ID  Name        StartDate   EndDate     Type
==================================================
1   John Smith  01/01/2014  19/01/2014  A
8   John Smith  20/01/2014  31/01/2014  AB
2   John Smith  01/02/2014  20/02/2014  B
3   John Smith  01/03/2014  17/03/2014  A
9   John Smith  18/03/2014  24/03/2014  AB
3   John Smith  25/03/2014  28/03/2014  A
5   John Smith  01/07/2014  14/07/2014  A
10  John Smith  15/07/2014  31/07/2014  AB
11  John Smith  25/07/2014  31/07/2014  ABC
7   John Smith  01/08/2014  25/08/2014  C

虽然下图不是上述图像的精确反映,但出于说明目的,我有兴趣查看同一结果集中重叠的日期(红色)和不重叠的日期(天蓝色)。

http://imgur.com/SeR9sY1

【问题讨论】:

  • 你不能只使用BETWEEN,然后把日期范围放在那里吗?

标签: sql sql-server database tsql


【解决方案1】:

如果您只想要重叠的时期,您可以通过自加入来获得。请注意,如果在某些日期有两个以上的时间段重叠,则结果可能是多余的。

select ft.name,
       (case when max(ft.startdate) > max(ft2.startdate) then max(ft.startdate)
             else max(ft2.startdate)
        end) as startdate,
       (case when min(ft.enddate) > min(ft2.enddate) then min(ft.enddate)
             else min(ft2.enddate)
        end) as enddate
from followingtable ft join
     followingtable ft2
     on ft.name = ft2.name and
        ft.id < ft2.id and
        ft.startdate <= ft2.enddate and
        ft.enddate > ft2.startdate
group by ft.name, ft.id, ft2.id;

这不会分配ids。您可以使用 row_number() 和偏移量来做到这一点。

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    相关资源
    最近更新 更多