使用 LEAD 函数筛选为连续值的一个实例的连续行的日期差异
Date difference over consecutive rows filtered to one instance of consecutive values using LEAD function
基本上我需要的结果是每个项目的价格变化范围,我需要提取项目价格和交易日期,结束日期设置为下一次项目价格变化。
鉴于此 table
create table myTable(id int, Price decimal(10,6), StartDate datetime)
insert into myTable
select 1, 92.576842, '2018-04-06 23:00:00.000' union all
select 1, 92.700000, '2018-04-12 21:39:00.000' union all
select 1, 92.700000, '2018-04-26 00:01:00.000' union all
select 1, 92.700000, '2018-06-04 23:20:00.000' union all
select 1, 116.700000, '2018-07-04 21:38:00.000' union all
select 1, 116.700000, '2018-08-01 22:31:31.000' union all
select 1, 118.610597, '2018-08-13 23:34:22.000' union all
select 1, 116.700000, '2018-09-05 23:52:28.000'
和这个查询
select id, Price, StartDate, LEAD(StartDate) over (partition by id order by id, StartDate) endDate
from myTable
order by id, StartDate
查询结果:
id Price StartDate endDate
1 92.576842 2018-04-06 23:00:00.000 2018-04-12 21:39:00.000
1 92.700000 2018-04-12 21:39:00.000 2018-04-26 00:01:00.000
1 92.700000 2018-04-26 00:01:00.000 2018-06-04 23:20:00.000
1 92.700000 2018-06-04 23:20:00.000 2018-07-04 21:38:00.000
1 116.700000 2018-07-04 21:38:00.000 2018-08-01 22:31:31.000
1 116.700000 2018-08-01 22:31:31.000 2018-08-13 23:34:22.000
1 118.610597 2018-08-13 23:34:22.000 2018-09-05 23:52:28.000
1 116.700000 2018-09-05 23:52:28.000 NULL
如何只获取连续 Price
个实例的最早日期
结果应如下所示 - 请注意最后一行是重复的 Price
但它是必需的
id Price StartDate EndDate
1 92.576842 2018-04-06 23:00:00.000 2018-04-12 21:39:00.000
1 92.700000 2018-04-12 21:39:00.000 2018-07-04 21:38:00.000
1 116.700000 2018-07-04 21:38:00.000 2018-08-13 23:34:22.000
1 118.610597 2018-08-13 23:34:22.000 2018-09-05 23:52:28.000
1 116.700000 2018-09-05 23:52:28.000 NULL
这是 "islands" 的一种方法,它采用 2 row_number() 计算,为 "island" 中的所有行提供一个共享 ID,然后可以按该 ID 进行分组:
select
id, Price, group_id, min(StartDate) StartDate, max(enddate) enddate
from (
select id, Price, StartDate
, LEAD(StartDate,1,DATEADD(YEAR,1,StartDate)) over (partition by id order by id,StartDate) endDate
, row_number() over(partition by id order by StartDate ASC)
- row_number() over(partition by id, price order by StartDate ASC) AS group_id
from myTable
) d
group by
id, Price, group_id
order by
id,StartDate
;
| id | Price | group_id | StartDate | enddate |
|----|------------|----------|----------------------|----------------------|
| 1 | 92.576842 | 0 | 2018-04-06T23:00:00Z | 2018-04-12T21:39:00Z |
| 1 | 92.7 | 1 | 2018-04-12T21:39:00Z | 2018-07-04T21:38:00Z |
| 1 | 116.7 | 4 | 2018-07-04T21:38:00Z | 2018-08-13T23:34:22Z |
| 1 | 118.610597 | 6 | 2018-08-13T23:34:22Z | 2018-09-05T23:52:28Z |
| 1 | 116.7 | 5 | 2018-09-05T23:52:28Z | 2019-09-05T23:52:28Z |
http://sqlfiddle.com/#!18/293d1/6
如果您希望 NULL 作为最后一个结束日期,请更改 lead() 使其不提供默认值
LEAD(StartDate,1)) over (partition by id order by id,StartDate) endDate
基本上我需要的结果是每个项目的价格变化范围,我需要提取项目价格和交易日期,结束日期设置为下一次项目价格变化。
鉴于此 table
create table myTable(id int, Price decimal(10,6), StartDate datetime)
insert into myTable
select 1, 92.576842, '2018-04-06 23:00:00.000' union all
select 1, 92.700000, '2018-04-12 21:39:00.000' union all
select 1, 92.700000, '2018-04-26 00:01:00.000' union all
select 1, 92.700000, '2018-06-04 23:20:00.000' union all
select 1, 116.700000, '2018-07-04 21:38:00.000' union all
select 1, 116.700000, '2018-08-01 22:31:31.000' union all
select 1, 118.610597, '2018-08-13 23:34:22.000' union all
select 1, 116.700000, '2018-09-05 23:52:28.000'
和这个查询
select id, Price, StartDate, LEAD(StartDate) over (partition by id order by id, StartDate) endDate
from myTable
order by id, StartDate
查询结果:
id Price StartDate endDate
1 92.576842 2018-04-06 23:00:00.000 2018-04-12 21:39:00.000
1 92.700000 2018-04-12 21:39:00.000 2018-04-26 00:01:00.000
1 92.700000 2018-04-26 00:01:00.000 2018-06-04 23:20:00.000
1 92.700000 2018-06-04 23:20:00.000 2018-07-04 21:38:00.000
1 116.700000 2018-07-04 21:38:00.000 2018-08-01 22:31:31.000
1 116.700000 2018-08-01 22:31:31.000 2018-08-13 23:34:22.000
1 118.610597 2018-08-13 23:34:22.000 2018-09-05 23:52:28.000
1 116.700000 2018-09-05 23:52:28.000 NULL
如何只获取连续 Price
个实例的最早日期
结果应如下所示 - 请注意最后一行是重复的 Price
但它是必需的
id Price StartDate EndDate
1 92.576842 2018-04-06 23:00:00.000 2018-04-12 21:39:00.000
1 92.700000 2018-04-12 21:39:00.000 2018-07-04 21:38:00.000
1 116.700000 2018-07-04 21:38:00.000 2018-08-13 23:34:22.000
1 118.610597 2018-08-13 23:34:22.000 2018-09-05 23:52:28.000
1 116.700000 2018-09-05 23:52:28.000 NULL
这是 "islands" 的一种方法,它采用 2 row_number() 计算,为 "island" 中的所有行提供一个共享 ID,然后可以按该 ID 进行分组:
select
id, Price, group_id, min(StartDate) StartDate, max(enddate) enddate
from (
select id, Price, StartDate
, LEAD(StartDate,1,DATEADD(YEAR,1,StartDate)) over (partition by id order by id,StartDate) endDate
, row_number() over(partition by id order by StartDate ASC)
- row_number() over(partition by id, price order by StartDate ASC) AS group_id
from myTable
) d
group by
id, Price, group_id
order by
id,StartDate
;
| id | Price | group_id | StartDate | enddate |
|----|------------|----------|----------------------|----------------------|
| 1 | 92.576842 | 0 | 2018-04-06T23:00:00Z | 2018-04-12T21:39:00Z |
| 1 | 92.7 | 1 | 2018-04-12T21:39:00Z | 2018-07-04T21:38:00Z |
| 1 | 116.7 | 4 | 2018-07-04T21:38:00Z | 2018-08-13T23:34:22Z |
| 1 | 118.610597 | 6 | 2018-08-13T23:34:22Z | 2018-09-05T23:52:28Z |
| 1 | 116.7 | 5 | 2018-09-05T23:52:28Z | 2019-09-05T23:52:28Z |
http://sqlfiddle.com/#!18/293d1/6
如果您希望 NULL 作为最后一个结束日期,请更改 lead() 使其不提供默认值
LEAD(StartDate,1)) over (partition by id order by id,StartDate) endDate