首页 > 解决方案 > SQL Server 滞后和领先

问题描述

我正在使用 SQL Server 2014。

我有一张桌子:

CREATE TABLE [dbo].tmpJobStatus
(
    [JobNum] [INT] NOT NULL,
    [Action] [VARCHAR](8) NULL,
    [ActionDate] [DATE] NULL,
    [SeqNum] [INT] NULL
) ON [PRIMARY]

我有一些数据:

INSERT INTO tmpJobStatus ([JobNum], [Action], [ActionDate], [SeqNum]) 
VALUES (12345, N'TEL', CAST(N'2019-07-05' AS Date), 19),
       (12345, N'AL2', CAST(N'2019-07-02' AS Date), 15),
       (12345, N'AL1', CAST(N'2019-05-28' AS Date), 8),
       (12345, N'TELA', CAST(N'2019-05-16' AS Date), 2),
       (6789, N'MAIN', CAST(N'2019-11-04' AS Date), 25),
       (6789, N'MAIN', CAST(N'2019-11-04' AS Date), 21),
       (6789, N'TEL', CAST(N'2019-10-29' AS Date), 20),
       (6789, N'MACO', CAST(N'2019-10-28' AS Date), 13),
       (6789, N'UCIN', CAST(N'2019-09-12' AS Date), 11)

如果我对一项作业执行LAGLEAD使用以下内容,我会得到所需的结果:

SELECT
    [JobNum],
    [ActionDate],
    [SeqNum],
    LAG(p.[Action]) OVER (ORDER BY p.[JobNum],p.[SeqNum]) FromActionCode,
    LEAD(p.[Action]) OVER (ORDER BY p.[JobNum],p.[SeqNum]) ToActionCode
FROM 
    [tmpJobStatus] p
WHERE
    [JobNum] = 6789
ORDER BY
    p.[JobNum], p.[SeqNum] DESC

结果:

JobNum  ActionDate  SeqNum  FromActionCode  ToActionCode
6789    2019-11-04  25    MAIN          NULL
6789    2019-11-04  21    TEL           MAIN
6789    2019-10-29  20    MACO          MAIN
6789    2019-10-28  13    UCIN          TEL
6789    2019-09-12  11    NULL          MACO

注意第一个 FromActionCode 和 LastToCode 的 NULL 是正确的。

但是,如果我查看所有记录,它会搞砸:

JobNum  ActionDate  SeqNum  FromActionCode  ToActionCode
6789    2019-11-04  25    MAIN              TELA
6789    2019-11-04  21    TEL               MAIN
6789    2019-10-29  20    MACO              MAIN
6789    2019-10-28  13    UCIN              TEL
6789    2019-09-12  11    NULL              MACO
12345   2019-07-05  19    AL2               NULL
12345   2019-07-02  15    AL1               TEL
12345   2019-05-28  8     TELA              AL2
12345   2019-05-16  2     MAIN              AL1

我错过了什么?

标签: sqlsql-servertsqllaglead

解决方案


你试过了吗PARTITION

SELECT [JobNum], [ActionDate], [SeqNum],
       LAG(p.[Action]) OVER (PARTITION BY p.[JobNum] ORDER BY p.[SeqNum]) FromActionCode,
       LEAD(p.[Action]) OVER (PARTITION BY p.[JobNum] ORDER BY p.[SeqNum]) ToActionCode
FROM [tmpJobStatus] p
ORDER BY p.[JobNum],p.[SeqNum] desc

推荐阅读