使用LEAD函数将连续行的日期差过滤为一个连续值实例

时间:2018-09-10 21:56:02

标签: sql-server-2014 data-partitioning lead

基本上,我需要的结果是每个商品的价格变化范围,我需要提取商品价格和交易日期,并在下一次更改商品价格时设置结束日期。

给出此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

1 个答案:

答案 0 :(得分:1)

这是一种用于“岛”的方法,该方法使用2个row_number()计算来为“岛”中的所有行提供一个共享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