SQL - 按连续日期对行进行分组
SQL - Group rows by contiguous date
我有一个table:
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 有用吗?如何使用?
对于 RDBMS 支持的 window 函数(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
我认为在这种情况下行号的差异更简单:
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);
行号的不同定义了您想要的组。起初这有点难看。 . .如果您盯着子查询的结果看,就会明白它是如何工作的。
我有一个table:
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 有用吗?如何使用?
对于 RDBMS 支持的 window 函数(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
我认为在这种情况下行号的差异更简单:
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);
行号的不同定义了您想要的组。起初这有点难看。 . .如果您盯着子查询的结果看,就会明白它是如何工作的。