根据记录(即行)之间经过的时间长度重新计算开始和结束日期
Re-calculate start and end dates based on length of time elapsed between records (i.e., rows)
我被难住了。我在 SQL 服务器数据库中有时间序列数据。每行代表客户入住酒店的时间。但是,有时客户会延长住宿时间、更换房间等,这些都会作为单独的预订记录在系统中。出于我们的目的,我需要将那些连续的 'bookings' 视为持续停留。考虑数据:
| CUSTOMERID | STARTDATE | ENDDATE |
| -------- | -----------| -------- |
| 1 |2021-07-02 |2021-07-14|
| 1 |2021-07-19 |2021-07-27|
| 2 |2018-11-12 |2018-11-16|
| 2 |2018-11-17 |2018-11-19|
| 2 |2018-11-19 |2018-11-25|
| 2 |2019-01-10 |2019-01-15|
我需要做的是汇总任何两条记录,其中客户下次访问的 STARTDATE
与当前记录的 ENDDATE
相差 <=1 天。换句话说,两次访问之间必须有一个完整的日历日才能将它们视为不同的。我需要最后的 table 看起来像这样:
| CUSTOMERID | STARTDATE | ENDDATE |NEWSTARTDATE|NEWENDDATE|
| -------- | -----------| -------- |------------|----------|
| 1 |2021-07-02 |2021-07-14|2021-07-02 |2021-07-14|
| 1 |2021-07-19 |2021-07-27|2021-07-19 |2021-07-27|
| 2 |2018-11-12 |2018-11-16|2018-11-12 |2018-11-25|
| 2 |2018-11-17 |2018-11-19|2018-11-12 |2018-11-25|
| 2 |2018-11-19 |2018-11-25|2018-11-12 |2018-11-25|
| 2 |2019-01-10 |2019-01-15|2019-01-10 |2019-01-15|
感谢@lptr 的回答,在子查询的 case 语句中包含一个 window 函数。请参阅下面的 link:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=f2c905f2c31675c179d9f2100d74f44f
create table t(CUSTOMERID int, STARTDATE date, ENDDATE date);
insert into t(CUSTOMERID , STARTDATE , ENDDATE )
values
(1, '2021-07-02', '2021-07-14'),
(1, '2021-07-19', '2021-07-27'),
(2, '2018-11-12', '2018-11-16'),
(2, '2018-11-17', '2018-11-19'),
(2, '2018-11-19', '2018-11-25'),
(2, '2019-01-10', '2019-01-15');
select CUSTOMERID , STARTDATE , ENDDATE,
max(sdate) over(partition by CUSTOMERID order by STARTDATE ) as NewStartDate,
min(edate) over(partition by CUSTOMERID order by STARTDATE rows between current row and unbounded following) as NewEndDate
from
(
select *,
case when STARTDATE <= lag(dateadd(day, 1, ENDDATE)) over(partition by CUSTOMERID order by STARTDATE ) then null
else STARTDATE
end as sdate,
case when ENDDATE>= lead(dateadd(day, -1, STARTDATE )) over(partition by CUSTOMERID order by STARTDATE ) then null
else ENDDATE
end as edate
from t
) as t
order by STARTDATE ;
我被难住了。我在 SQL 服务器数据库中有时间序列数据。每行代表客户入住酒店的时间。但是,有时客户会延长住宿时间、更换房间等,这些都会作为单独的预订记录在系统中。出于我们的目的,我需要将那些连续的 'bookings' 视为持续停留。考虑数据:
| CUSTOMERID | STARTDATE | ENDDATE |
| -------- | -----------| -------- |
| 1 |2021-07-02 |2021-07-14|
| 1 |2021-07-19 |2021-07-27|
| 2 |2018-11-12 |2018-11-16|
| 2 |2018-11-17 |2018-11-19|
| 2 |2018-11-19 |2018-11-25|
| 2 |2019-01-10 |2019-01-15|
我需要做的是汇总任何两条记录,其中客户下次访问的 STARTDATE
与当前记录的 ENDDATE
相差 <=1 天。换句话说,两次访问之间必须有一个完整的日历日才能将它们视为不同的。我需要最后的 table 看起来像这样:
| CUSTOMERID | STARTDATE | ENDDATE |NEWSTARTDATE|NEWENDDATE|
| -------- | -----------| -------- |------------|----------|
| 1 |2021-07-02 |2021-07-14|2021-07-02 |2021-07-14|
| 1 |2021-07-19 |2021-07-27|2021-07-19 |2021-07-27|
| 2 |2018-11-12 |2018-11-16|2018-11-12 |2018-11-25|
| 2 |2018-11-17 |2018-11-19|2018-11-12 |2018-11-25|
| 2 |2018-11-19 |2018-11-25|2018-11-12 |2018-11-25|
| 2 |2019-01-10 |2019-01-15|2019-01-10 |2019-01-15|
感谢@lptr 的回答,在子查询的 case 语句中包含一个 window 函数。请参阅下面的 link:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=f2c905f2c31675c179d9f2100d74f44f
create table t(CUSTOMERID int, STARTDATE date, ENDDATE date);
insert into t(CUSTOMERID , STARTDATE , ENDDATE )
values
(1, '2021-07-02', '2021-07-14'),
(1, '2021-07-19', '2021-07-27'),
(2, '2018-11-12', '2018-11-16'),
(2, '2018-11-17', '2018-11-19'),
(2, '2018-11-19', '2018-11-25'),
(2, '2019-01-10', '2019-01-15');
select CUSTOMERID , STARTDATE , ENDDATE,
max(sdate) over(partition by CUSTOMERID order by STARTDATE ) as NewStartDate,
min(edate) over(partition by CUSTOMERID order by STARTDATE rows between current row and unbounded following) as NewEndDate
from
(
select *,
case when STARTDATE <= lag(dateadd(day, 1, ENDDATE)) over(partition by CUSTOMERID order by STARTDATE ) then null
else STARTDATE
end as sdate,
case when ENDDATE>= lead(dateadd(day, -1, STARTDATE )) over(partition by CUSTOMERID order by STARTDATE ) then null
else ENDDATE
end as edate
from t
) as t
order by STARTDATE ;