Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Lead()- und LAG()-Funktionalität in SQL Server 2008

Sie sind auf dem richtigen Weg, indem Sie den Tisch mit sich selbst verbinden. Ich habe unten 2 Methoden dazu aufgeführt, die hier gut funktionieren sollten. Der erste Trick liegt in Ihrer ROW_NUMBER , achten Sie darauf, nach Benutzer-ID zu partitionieren und nach Datum zu sortieren. Dann können Sie entweder einen INNER JOIN verwenden mit Aggregation oder CROSS APPLY um Ihre laufenden Summen zu erstellen.

Aufbau der Daten mit der partitionierten ROW_NUMBER() :

DECLARE @Data TABLE (
    RowNum INT,
    UserId INT,
    Date DATE,
    Miles INT
)
INSERT @Data 
    SELECT
        ROW_NUMBER() OVER (PARTITION BY UserId
            ORDER BY Date) AS RowNum,
        *
    FROM (
        SELECT 1, '2015-01-01', 5
        UNION ALL SELECT 1, '2015-01-02', 6
        UNION ALL SELECT 2, '2015-01-01', 7
        UNION ALL SELECT 2, '2015-01-02', 3
        UNION ALL SELECT 2, '2015-01-03', 2
        ) T (UserId, Date, Miles)

Verwenden Sie INNER JOIN mit Aggregation

SELECT
    D1.UserId,
    D1.Date,
    D1.Miles,
    SUM(D2.Miles) AS [Total]
FROM @Data D1
    INNER JOIN @Data D2
        ON D1.UserId = D2.UserId
            AND D2.RowNum <= D1.RowNum
GROUP BY
    D1.UserId,
    D1.Date,
    D1.Miles

Verwenden Sie CROSS APPLY für die laufende Summe

SELECT
    UserId,
    Date,
    Miles,
    Total
FROM @Data D1
    CROSS APPLY (
        SELECT SUM(Miles) AS Total
        FROM @Data
        WHERE UserId = D1.UserId
            AND RowNum <= D1.RowNum
    ) RunningTotal

Die Ausgabe ist für jede Methode gleich:

UserId      Date       Miles       Total
----------- ---------- ----------- -----------
1           2015-01-01 5           5
1           2015-01-02 6           11
2           2015-01-01 7           7
2           2015-01-02 3           10
2           2015-01-03 2           12