选项 #1:使用 MS SQL SERVER 2008
使用时间戳排序,我们可以使用rank()
函数和临时表。也可以使用 CTE 和表变量。性能是一个棘手的部分,所以如果将来要重复这三个选项,我建议测试这三个选项。我将展示两个示例:
临时表(在 SQLFiddle 中尝试):
select rank() OVER (ORDER BY order_timestamp) as 'Rank', status into temp1 from temp
select t1.status as status, case when t1.status - t2.status = 0 then 'not changed' else 'changed' end as changed
from temp1 t1, temp1 t2
where t1.Rank = t2.Rank + 1
drop table temp1
CTE(在 SQLFiddle 中尝试):
with CTE_temp as (
select rank() OVER (ORDER BY order_timestamp) as 'Rank', *
from temp
)
select t1.status as status, case when t1.status - t2.status = 0 then 'not changed' else 'changed' end as changed
from CTE_temp t1, CTE_temp t2
where t1.Rank = t2.Rank + 1
选项 #2:使用 MS SQL SERVER 2012
MS SQL SERVER 2012 引入lead
和lag
( http://blog.sqlauthority.com/2011/11/15/sql-server-introduction-to-lead-and-lag-analytic-functions-introduced-in-sql-server-2012 /)。
在这种情况下,选项 #1 仍然有效,但您也可以尝试@RomanPekar 的解决方案。
更新:
基于@RomanPekar 的评论(以及某人的反对票),我不得不说临时表可以比 CTE 和表变量更好地执行,尤其是在需要大量数据时。优化器可以使用临时表中的统计信息来建立其查询计划,这可以提高性能。
同样,根据 OP 之后想要提供数据的用途(可能是更多查询),临时表仍然存在,不必执行新查询,并且在这些情况下可以使用索引来提高性能。
顺便说一句,破解我的答案并将其转换为 CTE 或表变量很容易,所以如果这是他将来会重复的操作,我建议 OP 测试这三种情况的性能。