SQL - 按连续日期

时间:2017-11-19 10:29:49

标签: sql gaps-and-islands

我有一张桌子:

Value   Date 
100     01/01/2000
110     01/05/2002
100     01/10/2003
100     01/12/2004

我想以这种方式对数据进行分组

Value       StartDate      EndDate
100         01/01/2000     30/04/2002
110         01/05/2002     30/09/2003
100         01/10/2003     NULL --> or value like '01/01/2099'

我怎样才能做到这一点? CTE是否有用以及如何使用?

2 个答案:

答案 0 :(得分:0)

对于RDBMS支持的窗口函数(MS SQL数据库上的示例):

with Test(value, dt) as(
  select 100, cast('2000-01-01' as date) union all
  select 110, cast('2002-05-01' as date) union all  
  select 100, cast('2003-10-01' as date) union all
  select 100, cast('2004-12-01' as date)
)
select max(value) value, min(dt) startDate, max(end_dt) endDate
  from (
     select a.*, sum(brk) over(order by dt) grp
       from (
         select t.*,
                case when value!=lag(value) over(order by dt) then 1 else 0 end brk,
                DATEADD(DAY,-1,lead(dt,1,cast('2099-01-02' as date)) over(order by dt)) end_dt
          from Test t
      ) a
  ) b
 group by grp
 order by startDate

答案 1 :(得分:0)

我认为在这种情况下行号的差异更简单:

select value, min(date) as endDate,
       dateadd(day, -1, lead(min(date)) over (order by min(date))) as endDate
from (select t.*,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by value order by date) as seqnum_v
      from t
     ) t
group by value, (seqnum - seqnum_v);

行号的不同定义了您想要的组。起初有点难以看到。 。 。如果你盯着子查询的结果,你就会看到它是如何工作的。