Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Fonctionnalité Lead() et LAG() dans SQL Server 2008

Vous êtes sur la bonne voie en joignant la table à elle-même. J'ai inclus 2 méthodes pour le faire ci-dessous qui devraient bien fonctionner ici. La première astuce est dans votre ROW_NUMBER , assurez-vous de partitionner par ID utilisateur et de trier par date. Ensuite, vous pouvez utiliser soit un INNER JOIN avec agrégation ou CROSS APPLY pour construire vos totaux cumulés.

Configuration des données avec le ROW_NUMBER() partitionné :

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)

Utilisez INNER JOIN avec agrégation

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

Utilisez CROSS APPLY pour le total cumulé

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

Le résultat est le même pour chaque méthode :

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