1

我经常在 SQLServer 中验证日志,我的查询通常如下所示(其中 Type = 0 表示错误):

SELECT * 
FROM Logs 
WHERE Type = 0 
ORDER BY Timestamp

但大多数时候,我不仅对错误本身感兴趣,而且对错误之前发生的事情感兴趣。

是否可以使用 SQLServer 查询匹配查询的 WHERE 子句的每一行上方/下方(相对于主键)的 n 行?

前任。通过我的查询,我只会得到第 125 和 130 行。我想要 [123、124、125] 和 [128、129、130]。

PrimaryKey  Timestamp             Type  Description
123         2012-09-17 03:41:46.240 1   Working.
124         2012-09-17 03:42:46.240 1   Database backup.
125         2012-09-17 03:43:46.240 0   Access violation.
126         2012-09-17 03:44:46.240 1   Working.
127         2012-09-17 03:45:46.240 1   Working.
128         2012-09-17 03:46:46.240 1   Working.
129         2012-09-17 03:47:46.240 1   Backup.
130         2012-09-17 03:48:46.240 0   Corrupted.
131         2012-09-17 03:49:46.240 1   Working.

谢谢你。

4

1 回答 1

2

我会这样做:

SELECT 
    L2.* 
FROM 
    Logs L1
    JOIN Logs L2
    ON 
        L1.PrimaryKey = L2.PrimaryKey OR 
        L1.PrimaryKey = L2.PrimaryKey - 1 OR
        L1.PrimaryKey = L2.PrimaryKey + 1
WHERE
    L1.Type = 0

结果如下:

PrimaryKey  TS                      Type        Description
----------- ----------------------- ----------- -----------------
124         2012-09-17 03:42:46.240 1           Database backup.
125         2012-09-17 03:43:46.240 0           Access violation.
126         2012-09-17 03:44:46.240 1           Working.
129         2012-09-17 03:47:46.240 1           Backup.
130         2012-09-17 03:48:46.240 0           Corrupted.
131         2012-09-17 03:49:46.240 1           Working.

您可以使用关系运算符修改连接条件以检索n匹配行上方和下方的行。

如果不保证 PrimaryKey 列是连续的,那么假设记录总是按Timestamp顺序ASC排序,以下查询将获取之前和之后的记录到选定的记录:

WITH LogsTable (PrimaryKey, TS, Type, Description, Rank) AS
(
    SELECT 
        PrimaryKey, 
        TS, 
        Type, 
        Description, 
        ROW_NUMBER() OVER (ORDER BY TS ASC) as 'Rank' 
    FROM 
        Logs
)
SELECT 
    L2.* 
FROM 
    LogsTable L1
    JOIN LogsTable L2
    ON 
        L1.Rank = L2.Rank OR 
        L1.Rank = L2.Rank - 1 OR
        L1.Rank = L2.Rank + 1
WHERE
    L1.Type = 0
于 2012-09-21T18:10:57.623 回答