使用 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