Может ли lead() возвращать следующую строку только при выполнении условия?

#tsql #sql-server-2016

#tsql #sql-server-2016

Вопрос:

Недавно моя компания обновилась с SQL Server 2008 до 2016, поэтому я хочу воспользоваться некоторыми «новыми» функциями, одной из которых является lead() .

Я понимаю основное использование, но я хочу знать, могу ли я вернуть следующую строку только при выполнении условия. Мой исходный запрос выглядел следующим образом, где x.next_id is null , если следующая строка не превышает 12 дней после текущей строки.

 SELECT 
    a.id, 
    a.date_a, 
    x.next_id
FROM 
    table a
OUTER APPLY
    (SELECT TOP 1 
         next_id = i.intIndex
     FROM 
         table i
     WHERE 
         i.date_a > DATEADD(DAY, 12, a.date_a)
     ORDER BY
         date_a, id ASC) x
ORDER BY
    date_a, id ASC
  

Данные могут выглядеть следующим образом, где третий столбец добавляется запросом:

 id        date_a       next_id
--------------------------------
1798678   2014-12-01   NULL
1798689   2013-01-05   1798688
1798688   2014-03-31   NULL
1798696   2013-04-03   1798694
1798694   2013-08-12   1798691
1798691   2014-09-30   NULL
1798698   2013-05-14   1798697
1798697   2013-08-29   NULL
  

Комментарии:

1. Примеры данных и ожидаемые результаты помогут нам помочь вам.

2. Я не уверен LEAD , что это поможет вам здесь, например, если у вас было 3 строки в последовательные даты, а не 4-я, то есть 20 дней спустя, все предыдущие строки должны были бы показывать дату на 20 дней позже. Это не так LEAD работает,

3. Если я выполняю ваш запрос для вашего набора данных, я получаю другой результат для вашего набора данных. Не могли бы вы предоставить четкий и правильный набор данных, пожалуйста?

Ответ №1:

Предполагая, что этот набор данных (ваша таблица результатов; минус столбец результатов):

 CREATE TABLE some_table(id INT PRIMARY KEY,date_a DATE);
INSERT INTO some_table(id,date_a)
VALUES (1798678,'2014-12-01'),
(1798689,'2013-01-05'),
(1798688,'2014-03-31'),
(1798696,'2013-04-03'),
(1798694,'2013-08-12'),
(1798691,'2014-09-30'),
(1798698,'2013-05-14'),
(1798697,'2013-08-29');
  

Этот запрос возвращает тот же набор результатов, что и запрос, который возвращает ваш запрос:

 SELECT
    id,
    date_a,
    next_id=
        CASE WHEN LEAD(date_a) OVER (ORDER BY date_a,id)>DATEADD(DAY,12,date_a)
            THEN LEAD(id) OVER (ORDER BY date_a,id)
            ELSE NULL
        END
FROM
    some_table
ORDER BY
    date_a,id;
  

Комментарии:

1. Спасибо, это дает мне те же результаты. И производительность в нескольких тестах, которые я провел до сих пор, имеет впечатляющий прирост.