2012-09-21 4 views
1

특정 레코드 위 아래로 기록을 검색하고 (유형 = 0가 의미하는 경우 오류) 내 쿼리는 일반적으로 다음과 같습니다나는 종종 SQLServer에에서 로그를 확인

SELECT * 
FROM Logs 
WHERE Type = 0 
ORDER BY Timestamp 

그러나 대부분의 시간, 아니에요 오류 자체에 의해서만 관심이 있었고 오류 직전에 일어난 일에 대해서도 관심이있었습니다.

SQLServer를 사용하면 쿼리의 WHERE 절과 일치하는 각 줄 위/아래 (기본 키에 상대적인)에서 n 줄을 쿼리 할 수 ​​있습니까?

Ex. 내 질문으로 나는이라는 줄만 얻을 것이다. 나는 [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

다음 기본 키 열이 순차적으로 보장되어 있지 않은 경우

후 레코드가 항상 ASC 위해 Timestamp에 의해 정렬 가정, 다음 쿼리는 이전과 선택된 하나에 기록 후 가져옵니다 SQL Server의 어떤 버전입니까? –

+0

SQLServer 2008 – Illuna

답변

2

나는 그것을 할 것이다 :

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 라인을 검색하기 위해 관계 연산자를 사용하여 조인 조건을 수정할 수 있습니다 다음과 같이

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 

결과가 될 것이다 일치하는 라인.

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

@ Martinsmith, 당신 말이 맞아요. 나는 신분증이 순차적이라고 가정하고 있었다. 그렇지 않다면, 우리는'RANK() OVER (ORDER BY TS ASC)'를 사용하고 순위를 사용하여 선택된 레코드의 위와 아래의 레코드를 식별해야합니다. 그에 따라 내 대답이 업데이트되었습니다. 귀하의 회신에 감사드립니다. – Vikdor

관련 문제