ウィンドウ関数のヘルプが必要です。ウィンドウ内の合計とウィンドウ内の現在の合計を計算できることを知っています。しかし、以前の現在の合計、つまり現在の行を含まない現在の合計を計算することは可能ですか?
ROW
またはRANGE
引数を使用する必要があると思います。 CURRENT ROW
オプションが必要ですが、CURRENT ROW - 1
、これは無効な構文です。 ROW
引数とRANGE
引数についての私の知識は限られているので、どんな助けもありがたく受けられます。
この問題には多くの解決策があることは知っていますが、ROW
、RANGE
引数を理解しようとしています。これらの引数で問題を解読できると思います。以前の現在の合計を計算する1つの可能な方法を含めましたが、もっと良い方法があるかどうか疑問に思います。
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
答えは、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-Serverはデフォルトを使用します*RANGE UNBOUNDED PRECEDING AND CURRENT ROW
。効率の違いがあると思います。ROWS UNBOUNDED PRECEDING AND CURRENT ROW
をお勧めします(もちろん、テスト後、必要な結果が得られた場合)。
パフォーマンステストを含む @ Aaron Bertrand によるブログ記事で見つけることができるより多くの詳細:合計を実行するための最良のアプローチ– SQL Server 2012用に更新
* ORDER BY
がOVER
句内に存在する場合、これはもちろんデフォルトの範囲です。それ以外の場合、ORDER BY
がないと、デフォルトはパーティション全体になります。