選擇列值已更改的行:SQL 技術
確定列值經歷轉換的實例是各種情況下的關鍵操作數據分析場景。本文探討了有效識別表中此類變更的技術。
問題陳述
考慮下表中的「值」與「時間」欄位:
Value | Time | |
---|---|---|
0 | 15/06/2012 8:03:43 PM | |
1 | 15/06/2012 8:03:43 PM | * |
1 | 15/06/2012 8:03:48 PM | |
1 | 15/06/2012 8:03:53 PM | |
1 | 15/06/2012 8:03:58 PM | * |
2 | 15/06/2012 8:04:03 PM | * |
2 | 15/06/2012 8:04:08 PM | |
3 | 15/06/2012 8:04:13 PM | * |
3 | 15/06/2012 8:04:18 PM | |
3 | 15/06/2012 8:04:23 PM | |
2 | 15/06/2012 8:04:28 PM | * |
2 | 15/06/2012 8:04:33 PM |
任務是識別標有「*」的行,表示「值」中的轉換
解決方案
使用視窗函數(SQL Server 2012 及更高版本)
使用SQL Server中引入的視窗函數2012年,可以執行此操作高效:
;WITH x AS ( SELECT value, time, rn = ROW_NUMBER() OVER (PARTITION BY Value ORDER BY Time) FROM dbo.table ) SELECT * FROM x WHERE rn = 1;
此查詢計算「Value」的每個分區內的行號,並為每個分區選擇第一行(rn = 1)。
使用表格連結(SQL Server 2008 及更早版本)
對於2012 年之前的SQL Server 版本,以下內容可以使用方法:
DECLARE @x TABLE(value INT, [time] DATETIME) INSERT @x VALUES (0,'20120615 8:03:43 PM'),-- (1,'20120615 8:03:43 PM'),--* (1,'20120615 8:03:48 PM'),-- (1,'20120615 8:03:53 PM'),-- (1,'20120615 8:03:58 PM'),-- (2,'20120615 8:04:03 PM'),--* (2,'20120615 8:04:08 PM'),-- (3,'20120615 8:04:13 PM'),--* (3,'20120615 8:04:18 PM'),-- (3,'20120615 8:04:23 PM'),-- (2,'20120615 8:04:28 PM'),--* (2,'20120615 8:04:33 PM'); ;WITH x AS ( SELECT *, rn = ROW_NUMBER() OVER (ORDER BY time) FROM @x ) SELECT x.value, x.[time] FROM x LEFT OUTER JOIN x AS y ON x.rn = y.rn + 1 AND x.value <> y.value WHERE y.value IS NOT NULL;
此查詢在表上執行自聯接,比較相鄰行以識別值變更。它需要一個單獨的表變數來儲存中間結果。
注意:雖然視窗函數提供更好的效能,但它們可能並非在所有版本的 SQL Server 中都可用。選擇最適合您的版本和效能要求的方法。
以上是SQL中如何有效率地辨識列值變更的行?的詳細內容。更多資訊請關注PHP中文網其他相關文章!