ЗАДЕРЖКА работает только на первом ряду. игнорирует все остальные следующие строки

#sql-server

Вопрос:

Я использую SQL Server 2012 (стандарт). Похоже, функция ЗАДЕРЖКИ работает только в первой строке.

Мои исходные данные выглядят следующим образом (в табличной переменной)

select BatchId, [Day], Change, Opening, Closing from @Data

Данные до ЗАДЕРЖКИ

но этот запрос работает только с моим запросом только в первой строке

 SELECT  
BatchId,
[Day], 
LAG(Closing, 1, 500) OVER (PARTITION BY BatchId ORDER BY [Day] asc) as Opening,
Change,
(LAG(Closing, 1, 500) OVER (PARTITION BY BatchId ORDER BY [Day] asc) - Change) as Closing
FROM @Data
order by [Day] asc
 

что приводит к следующему:

Только строка 1 имеет допустимые значения

Закрытие-это в основном (Открытие — Изменение). Кажется, мне не хватает чего-то простого, потому что каждый пример, который я видел, выглядит одинаково

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

1. Мне кажется, что это работает правильно. Каждая строка имеет значение 0, поэтому 0 это правильное значение, если вы хотите указать значение предыдущей строки Closing . Я не думаю, что то, чего ты хочешь, — это всего LAG лишь совокупность SUM . Данные о потребляемых образцах и ожидаемые результаты помогут нам помочь вам.

2. Я предполагаю, что операция задержки работает строка за строкой по мере заполнения данных в результирующий набор. Правильно ли это по сравнению с тем, что он работает только с данными, уже содержащимися в таблице, до выполнения запроса? то есть он не работает динамически?

3. LAG возвращает значение столбца из предыдущей строки. Все ваши строки имеют значение 0 в ваших образцах данных, как я уже упоминал, поэтому предыдущая строка всегда будет 0 такой .

4. Опять же, если вы предоставите потребляемые образцы данных (не изображение) и ожидаемые результаты, мы можем показать вам, как достичь того, что вам нужно.

5. @Larnu, спасибо за идею о накопительной сумме. Я опубликовал свою новую реализацию ниже, и теперь, похоже, все в порядке

Ответ №1:

Благодаря комментарию Ларну за то, что он указал мне правильное направление, я выбрал выбор с совокупной суммой, как показано ниже:

 select BatchId, [Day], Change,
    500 - (sum(Change) OVER (ORDER BY [Day] asc) - Change) as Opening,
    sum(Change) OVER (ORDER BY [Day] asc) as CumChange, 
    500 - sum(Change) OVER (ORDER BY [Day] asc) as Closing  
from
@Data
group by BatchId, [Day], Change
 

500-это всего лишь начальная сумма открытия

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

введите описание изображения здесь

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

1. ORDER BY [Day] ROWS UNBOUNDED PRECEDING в противном случае вы получите неправильные результаты, если есть несколько строк с одним и тем же днем, это также лучше для производительности