运行总计到上一行


14

我需要有关开窗功能的帮助。我知道您可以计算一个窗口内的总和以及一个窗口内的运行总额。但是是否可以计算先前的运行总计,即运行总计不包括当前行?

我认为您将需要使用ROWor RANGE参数。我知道有一个CURRENT ROW选项,但我需要CURRENT ROW - 1,这是无效的语法。我对ROWRANGE参数的了解有限,因此将非常感谢您的帮助。

我知道有这个问题的许多解决方案,但我看明白了ROWRANGE争论,我以为这个问题可以用这些被破解。我提供了一种可能的方法来计算以前的总运行量,但我想知道是否有更好的方法:

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

Answers:


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 Server使用默认的* RANGE UNBOUNDED PRECEDING AND CURRENT ROW。我认为这存在效率差异,ROWS UNBOUNDED PRECEDING AND CURRENT ROW因此应该优先考虑(当然要经过测试,如果能给出想要的结果)。

您可以在@Aaron Bertrand的博客文章中找到更多详细信息,包括性能测试:运行总计的最佳方法–已针对SQL Server 2012更新

*当子句中ORDER BY存在时,这当然是默认范围OVER-否则,没有ORDER BY默认范围的是整个分区。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.