我经常验证SQLServer中的日志,我的查询通常看起来像这样(其中Type = 0表示错误):
SELECT *
FROM Logs
WHERE Type = 0
ORDER BY Timestamp
但是大多数时候,我不仅对错误本身感兴趣,而且对错误发生之前发生的事情感兴趣。
使用SQLServer,是否有可能在查询的WHERE子句的每一行上查询上面/下面(相对于主键)的n行?
实施例。根据我的查询,我只能获得第125和第10行。 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.
谢谢。
答案 0 :(得分: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