2013-05-24 11 views
5

Ich brauche etwas Hilfe mit Fensterfunktionen.SQL Server 2012 Windowing-Funktion zum Berechnen einer laufenden Summe

Ich habe vor kurzem mit sql 2012 Fensterfunktionen gespielt. Ich weiß, dass Sie die Summe innerhalb eines Fensters und die laufende Summe innerhalb eines Fensters berechnen können. Aber ich habe mich gefragt; Ist es möglich, die vorherige laufende Summe zu berechnen, d. h. die laufende Summe ohne die aktuelle Zeile? Ich nehme an, Sie müssten das Argument ROW oder RANGE verwenden und ich weiß, dass es eine Option CURRENT ROW gibt, aber ich würde eine AKTUELLE REIHE - I, die ungültige Syntax ist. Mein Wissen über die ROW- und RANGE-Argumente ist begrenzt, so dass jede Hilfe dankbar angenommen wird.

Ich weiß, dass es viele Lösungen für dieses Problem gibt, aber ich bin auf der Suche nach den ROW, RANGE-Argumenten und ich nehme an, das Problem kann mit diesen geknackt werden. Ich habe einen möglichen Weg zur Berechnung des vorherigen laufenden Gesamtbetrags eingeschlossen, aber ich frage mich, ob es einen besseren Weg gibt.

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 

Vielen Dank im Voraus

+1

Bitte kreuzen Sie nicht Post auf beiden [Datenbank-Administratoren] (http://dba.stackexchange.com/questions/42985/sql-windowing-function-to-create- a-running-total) und hier, außer wenn die Antwort von der Perspektive eines Programmierers gegenüber der dba abweichen könnte. –

Antwort

20

Sie können die aktuelle Zeile den Wert subtrahieren:

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

Oder nach dem syntax at MSDN und ypercube's answer:

<window frame preceding> ::= 
{ 
    UNBOUNDED PRECEDING 
    | <unsigned_value_specification> PRECEDING 
    | CURRENT ROW 
} 

->

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