Функции Lead() и LAG() в SQL Server 2008

Надеюсь, что все SQL-гуру там отлично работают:)

Я пытаюсь симулировать LEAD() а также LAG() функциональность в SQL Server 2008.

Это мой сценарий: у меня есть временная таблица, которая заполняется с использованием базового запроса с бизнес-логикой для пробега. Я хочу рассчитать накопленный пробег для каждого пользователя в день.

Временная таблица настраивается с помощью ROW_NUMBER(), поэтому у меня есть все данные, необходимые в таблице временных значений, кроме накопленного пробега.

Я попытался использовать CTE с базовым запросом и самостоятельно соединиться с самим собой и не смог заставить его работать. Я прилагаю снимок экрана для того же.

Любая помощь / предложение будет оценено.

1 ответ

Вы на правильном пути, присоединив стол к себе. Я включил 2 способа сделать это ниже, которые должны хорошо работать здесь. Первый трюк в вашем ROW_NUMBER, обязательно разделите по идентификатору пользователя и отсортируйте по дате. Тогда вы можете использовать любой INNER JOIN с агрегацией или CROSS 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
Другие вопросы по тегам