假设我有2列的表:Revision,Value with entries:
+----------+-------+
| Revision | Value |
+----------+-------+
| 1 | John |
| 2 | John |
| 3 | James |
| 4 | James |
| 5 | John |
+----------+-------+
此表将用于跟踪某个值的变化
我想获取值更改时的版本号。所以对于上表,它将是1,3和5。
我尝试使用order by但是当James的值从James变回John
时,这将错过第二次出现答案 0 :(得分:4)
SQL-Server 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-Server 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) ;
进行测试
请注意,这两个查询都不依赖于Revision
数字是连续的(甚至是数字!)。如果您的数字没有差距,那么GoatCO的答案也相当不错。
答案 1 :(得分: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()
函数非常有用。