1

鉴于以下一组数据,我试图确定如何选择组合日期范围的开始和结束日期,当它们相互交叉时。

例如,对于 PartNum 115678,我希望我的最终结果集显示日期范围2012/01/01 - 2012/01/19(第 1 行、第 2 行和第 4 行合并,因为日期范围相交)和2012/02/01 - 2012/03/28(第 3 行,因为这些与之前找到的范围不相交)。

对于 PartNum 213275,我想选择该部分的唯一行,2012/12/01 - 2013/01/01.

示例数据

编辑:我目前正在使用以下 SQL 语句,但它并没有完全满足我的需要。

with DistinctRanges as (
    select distinct
        ha1.PartNum "PartNum",
        ha1.StartDt "StartDt",
        ha2.EndDt "EndDt"
    from dbo.HoldsAll ha1
    inner join dbo.HoldsAll ha2 
        on ha1.PartNum = ha2.PartNum
    where 
        ha1.StartDt <= ha2.EndDt 
        and ha2.StartDt <= ha1.EndDt
)
select 
    PartNum, 
    StartDt, 
    EndDt
from DistinctRanges

以下是编辑中显示的查询结果:

内联查询的结果

4

1 回答 1

3

你最好有一个持久的日历表,但如果你不这样做,下面的 CTE 将临时创建它。该TOP(36000)部分足以从'20100101'同一行的枢轴 ( ) 为您提供 10 年的日期。

SQL小提琴

MS SQL Server 2008 架构设置

create table data (
    partnum int,
    startdt datetime,
    enddt datetime,
    age int
);
insert data select 
12345, '20120101', '20120116', 15 union all select
12345, '20120115', '20120116', 1 union all select
12345, '20120201', '20120328', 56 union all select
12345, '20120113', '20120119', 6 union all select
88872, '20120201', '20130113', 43;

查询 1

with Calendar(thedate) as (
    select TOP(36600) dateadd(d,row_number() over (order by 1/0),'20100101')
      from sys.columns a
cross join sys.columns b
cross join sys.columns c
), tmp as (
   select partnum, thedate,
          grouper = datediff(d, dense_rank() over (partition by partnum order by thedate), thedate)
     from Calendar c
     join data d on d.startdt <= c.thedate and c.thedate <= d.enddt
)
select partnum, min(thedate) startdt, max(thedate) enddt
  from tmp
 group by partnum, grouper
 order by partnum, startdt

结果

| PARTNUM |                         STARTDT |                          ENDDT |
------------------------------------------------------------------------------
|   12345 |  January, 01 2012 00:00:00+0000 | January, 19 2012 00:00:00+0000 |
|   12345 | February, 01 2012 00:00:00+0000 |   March, 28 2012 00:00:00+0000 |
|   88872 | February, 01 2012 00:00:00+0000 | January, 13 2013 00:00:00+0000 |
于 2012-12-05T03:07:06.633 回答