检测列中的更改

时间:2014-04-01 17:34:32

标签: sql sql-server

假设我有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

时,这将错过第二次出现

2 个答案:

答案 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) ;

SQL-Fiddle.com

进行测试

请注意,这两个查询都不依赖于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()函数非常有用。