SQL Server 2008中的Lead()和LAG()功能

时间:2015-11-06 15:38:54

标签: sql-server-2008 tsql common-table-expression lag lead

希望所有的SQL GURUS都做得很好:)

我正在尝试在SQL Server 2008中模拟LEAD()LAG()功能。

这是我的场景:我有一个临时表,使用基本查询填充里程数的业务逻辑。我想计算每个用户每天的累积里程数。

临时表是使用ROW_NUMBER()设置的,因此除累计里程外,我还拥有临时表中所需的所有数据。

我尝试使用带有基本查询的CTE并自行加入,但无法使其正常工作。我正在附加屏幕截图。

任何帮助/建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

通过将表连接到自身,您走在正确的轨道上。我在下面提到了两种方法,在这里工作正常。第一个技巧是在ROW_NUMBER中,请确保按用户ID进行分区并按日期排序。然后,您可以使用带有聚合的INNER JOINCROSS APPLY来构建运行总计。

使用分区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)

使用带汇总的INNER JOIN

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

使用CROSS APPLY作为总计

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

每种方法的输出相同:

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