Невозможно получить данные с помощью функции LAG в SQL Server - PullRequest
0 голосов
/ 04 марта 2019

Не уверен, как получить данные с помощью функции задержки.

У меня есть эти данные:

date                        value   id
---------------------------------------
2019-03-01 00:00:00.000     1       a
2019-02-28 00:00:00.000     2       a
2019-02-27 00:00:00.000     3       a
2019-02-26 00:00:00.000     4       a
2019-03-01 00:00:00.000     4       b
2019-02-28 00:00:00.000     3       b
2019-02-27 00:00:00.000     2       b
2019-02-26 00:00:00.000     1       b

Мне нужно значение lag 1 и lag2, и для каждого идентификатора только 1 строка

 id  value lag1 lag2
--------------------
 a    1     2    3
 b    4     3    2

Мой запрос

select 
    id, date, value, 
    lag(value, 1) over (partition by id order by date),
    lag(value, 2) over (partition by id order by date) 
from 
    data;

Но я получаю более 1 строки, и для каждой строки вычисляется лаг.Я знаю, что функция ведет себя таким образом, но не может получить желаемый результат.Использовал другой запрос

select top 1 
from 
    (select 
         id, date, value, 
         lag(value, 1) over (partition by id order by date),
         lag(value, 2) over (partition by id order by date)
     from 
         data)

Это возвращает только 1 строку, но у меня есть несколько идентификаторов.Мне нужно ограничить 1 строку для каждого идентификатора.Любая помощь приветствуется

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

lag() - это оконная функция, поэтому она не меняет количество строк.Для этого вам нужна фильтрация.

Как насчет этого?

select id, date, value, value_1, value_2
from (select id, date, value,
             lag(value, 1) over (partition by id order by 
date) as value_1,
             lag(value, 2) over (partition by id order by date) as value_2,
             row_number() over (partition by id order by date desc) as seqnum
      from data
     ) d
where seqnum = 1
0 голосов
/ 04 марта 2019

Вы можете сделать агрегацию:

select t.id, 
       max(case when seq = 1 then value end) as value1,
       max(case when seq = 2 then value end) as value2,
       max(case when seq = 3 then value end) as value3,
       max(case when seq = 4 then value end) as value4,
       max(case when seq = 5 then value end) as value5
from (select t.*,
             row_number() over (partition by id order by date desc) as seq
      from table t
     ) t
group by t.id;
...