2012-09-21 93 views
1

我經常驗證的SQLServer日誌和我的查詢通常是這樣的(其中Type = 0表示錯誤):檢索的上方和下方的特定記錄的記錄

SELECT * 
FROM Logs 
WHERE Type = 0 
ORDER BY Timestamp 

但大部分的時間,我不只對錯誤本身感興趣,但也對錯誤發生之前發生的事情感興趣。

是否有可能使用SQLServer查詢每行匹配查詢的WHERE子句的上方/下方(相對於主鍵)的n行?

Ex。與我的查詢,我只會得到線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. 

謝謝。

+0

如果PrimaryKey的列不能保證是連續的,那麼假定記錄是由TimestampASC爲了總是命令,下面的查詢將之前和記錄選定一個後取什麼版本的SQL Server? –

+0

這是SQLServer 2008 – Illuna

回答

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線的上方和下方的連接條件匹配線。

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 
+0

謝謝你Vikdor,這是我正在尋找的東西! – Illuna

+0

你似乎認爲這些ID是連續保證的。 'IDENTITY'列不保證這一點。 –

+0

@馬丁史密斯,你是對的。我假設身份證是連續的。如果沒有,那麼我們應該使用'RANK()OVER(ORDER BY TS ASC)',並使用等級來標識所選記錄下方和上方的記錄。相應地更新我的答案。感謝您的答覆。 – Vikdor