2014-04-01 59 views
2

說我有表2列:修訂,值與輸入:檢測在列變化

+----------+-------+ | Revision | Value | +----------+-------+ | 1 | John | | 2 | John | | 3 | James | | 4 | James | | 5 | John | +----------+-------+

該表將被用來跟蹤某一值的變化

我想獲取值的更改時的版本號。因此,對於上面的表這將是1,3,和5

我試圖通過使用順序,但是當值從詹姆斯改回約翰

這將錯過第二次出現
+2

SQL-Server的版本? –

+0

查找滯後和領導 –

+0

Microsoft SQL Server 2008 R2(SP1) – Sebastian

回答

4

SQL-服務器2012+,使用LAG()功能:

; WITH cte AS 
(SELECT Revision, Value, 
     PreviousValue = LAG(Value) OVER (ORDER BY Revision) 
    FROM tableX 
) 
SELECT Revision, Value 
FROM cte 
WHERE Previousvalue <> Value 
    OR PreviousValue IS NULL ; 

SQL-服務器2005+,利用窗口函數:

; WITH cte AS 
(SELECT Revision, Value, 
     Rn = ROW_NUMBER() OVER (ORDER BY Revision), 
     Ln = ROW_NUMBER() OVER (PARTITION BY Value ORDER BY Revision) 
    FROM tableX 
) 
SELECT Revision = MIN(Revision), 
     Value 
FROM cte 
GROUP BY Value, (Rn-Ln) ; 

SQL-Fiddle.com

注意,這兩個測試查詢不依賴於Revision數字順序(甚至是數字!)。如果你的數字沒有差距,GoatCO的回答也相當不錯。

+0

在哪種情況下山羊的答案會失敗?另外,你能建議如何發生差距嗎? –

+3

身份(或自動生成)列存在差距的原因大約有10多種。回滾,刪除等... –

+2

我已經給我的答案添加了一個備註,因此,我應該包含一個重要的警告。在實踐中,我幾乎總是使用'ROW_NUMBER()',因爲我的數據很少有一個有用的連續整數值用於這種查詢。 –

2

您可以使用可自加入和偏移的修訂版本號:

SELECT a.Revision 
FROM Table1 a 
LEFT JOIN Table1 b 
ON a.Revision = b.Revision +1 
WHERE a.Value <> b.Value 
    OR b.Revision IS NULL 

輸出:

| REVISION | 
|----------| 
|  1 | 
|  3 | 
|  5 | 

演示:SQL Fiddle

更新:正如其他人所指出的,這個簡單的答案是基於修訂號碼是連續的。如果您的數據集沒有合適的數字用於偏移自聯接,則ROW_NUMBER()函數很有用。

+0

對於簡單和數據庫不可知的答案+1。 –

+0

@BoratSagdiyev Mine也是db不可知的:) –

+0

@ypercube - 在My-SQL,Oracles等中工作嗎?我不這麼認爲。它使用CTE。 Chenqui。 –