Запуск у попередньому рядку


14

Мені потрібна допомога щодо функцій вікон. Я знаю, що ви можете обчислити суму у вікні та загальну кількість у вікні. Але чи можна обчислити попередній загальний обсяг, тобто загальний запуск, не враховуючи поточний рядок?

Я припускаю, що вам потрібно буде використовувати аргумент ROWабо RANGEЯ знаю, що є CURRENT ROWваріант, але мені знадобиться CURRENT ROW - 1, а це недійсний синтаксис. Мої знання ROWта RANGEаргументи обмежені, тому будь-яка допомога буде вдячно отримана.

Я знаю , що є багато способів вирішення цієї проблеми, але я шукаю , щоб зрозуміти ROW, RANGEаргументи і я вважаю , що проблема може бути зламана з ними. Я включив один можливий спосіб обчислити попередній загальний облік, але мені цікаво, чи є кращий спосіб:

USE AdventureWorks2012

SELECT s.SalesOrderID
    , s.SalesOrderDetailID
    , s.OrderQty
    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID) AS RunningTotal
    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID 
                         ORDER BY SalesOrderDetailID) - s.OrderQty AS PreviousRunningTotal
    -- Sudo code - I know this does not work
    --, SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID 
    --                   ORDER BY SalesOrderDetailID
    --                   ROWS BETWEEN UNBOUNDED PRECEDING 
    --                                   AND CURRENT ROW - 1) 
    -- AS  SudoCodePreviousRunningTotal
FROM Sales.SalesOrderDetail s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID
    , s.SalesOrderDetailID 
    , s.OrderQty

Відповіді:


22

Відповідь - використовувати 1 PRECEDING, а не CURRENT ROW -1. Отже, у своєму запиті використовуйте:

    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID 
                            ORDER BY SalesOrderDetailID
                            ROWS BETWEEN UNBOUNDED PRECEDING 
                                     AND 1 PRECEDING) 
    AS  PreviousRunningTotal

Також врахуйте, що у вашому іншому розрахунку:

    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID
                            ORDER BY SalesOrderDetailID) ...

SQL-сервер використовує стандартний * RANGE UNBOUNDED PRECEDING AND CURRENT ROW . Я думаю, що є різниця в ефективності і її ROWS UNBOUNDED PRECEDING AND CURRENT ROWслід віддати перевагу (після тестування, звичайно, і якщо це дає потрібні результати).

Набагато більше деталей ви можете знайти в статті блогу @Aaron Bertrand , включаючи тести продуктивності: Найкращі підходи до запуску підсумків - оновлено для SQL Server 2012

* це, звичайно, діапазон за замовчуванням, коли ORDER BYв OVERпункті присутній ан - інакше без ORDER BYрозділу за замовчуванням є весь розділ.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.