Разница дат по последовательным строкам, отфильтрованным к одному экземпляру последовательных значений с помощью функции LEAD - PullRequest
0 голосов
/ 11 сентября 2018

В основном мне нужен результат - диапазоны изменения цены для каждого товара, мне нужно извлечь цену товара и дату транзакции с датой окончания, установленной на следующий раз, когда цена товара будет изменена.

Учитывая это таблица

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 голосов
/ 11 сентября 2018

Это подход для "островов", который использует 2 вычисления row_number (), которые дают всем строкам в "островке" общий идентификатор, тогда можно группировать по этому идентификатору:

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(StartDate,1)) over (partition by id order by id,StartDate) endDate
...