仅在具有相交期间的组记录

时间:2015-04-02 15:20:21

标签: sql sql-server

我有这样的表

   declare @data table
    (
        id int not null,
        groupid int not null,
        startDate datetime not null,
        endDate datetime not null   
    )


insert into @data values
(1, 1, '20150101', '20150131'),
(2, 1, '20150114', '20150131'),
(3, 1, '20150201', '20150228');

我目前的选择陈述是:

select groupid, 'some data', min(id), count(*)
from @data
group by groupid

但是现在我需要将记录分组,如果它已经相交了

期望的结果:

1, 'some data', 1, 2
1, 'some data', 3, 1

有人知道怎么做吗?

1 个答案:

答案 0 :(得分:1)

一种方法是识别每个组的开头 - 因为它与前一个组不重叠。然后,将这些数量计算为组标识符。

with overlaps as (
      select id
      from @data d
      where not exists (select 1
                        from @data d2
                        where d.groupid = d2.groupid and
                              d.startDate >= d2.startDate and
                              d.startDate < d2.endDate
                       )
     ),
     groups as (
      select d.*,
             count(o.id) over (partition by groupid
                               order by d.startDate) as grpnum
      from @data d left join
           overlaps o
           on d.id = o.id
     )
select groupid, min(id), count(*),
       min(startDate) as startDate, max(endDate) as endDate
from groups
group by grpnum, groupid;

注意:这是使用累积计数,可在SQL Server 2012+中使用。您可以在早期版本中使用相关子查询或apply执行类似操作。

此外,此查询假定开始日期是唯一的。如果不是,可以调整查询,但逻辑变得有点复杂。