Sql server 检索特定记录上方和下方的记录
我经常在SQLServer中验证日志,我的查询通常如下所示(其中Type=0表示错误): 但大多数时候,我不仅对错误本身感兴趣,而且对错误之前发生的事情也感兴趣 使用SQLServer,是否可以在与查询的WHERE子句匹配的每一行的上方/下方(相对于主键)查询n行 我的查询只能得到第125行和第130行。我想要[123124125]和[128129130]Sql server 检索特定记录上方和下方的记录,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我经常在SQLServer中验证日志,我的查询通常如下所示(其中Type=0表示错误): 但大多数时候,我不仅对错误本身感兴趣,而且对错误之前发生的事情也感兴趣 使用SQLServer,是否可以在与查询的WHERE子句匹配的每一行的上方/下方(相对于主键)查询n行 我的查询只能得到第125行和第130行。我想要[123124125]和[128129130] PrimaryKey Timestamp Type Description 123 2012-0
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.
谢谢。我会按如下方式做:
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.
结果如下:
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列不能保证是连续的,那么假设记录总是按ASC
顺序中的Timestamp
排序,下面的查询将把前后记录提取到所选的记录中:
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
谢谢你,维克多,这正是我想要的!不过,您似乎假设ID是连续的。
IDENTITY
列不能保证这一点。@MartinSmith,你说得对。我假设ID是连续的。如果没有,那么我们应该使用RANK()OVER(ORDER BY TS ASC)
并使用RANK来标识所选记录上下的记录。相应地更新了我的答案。感谢您的回复。在TS
上使用RANK()。可能是行号()
?