我有一个Document
表:
| ID| DOC_ID | Count|
1 22 1
2 22 1
3 22 2
4 22 2
5 22 2
6 22 3
我可以编写一个SQL查询,只返回计数发生变化的最新行吗?我正在使用SQL Server
期望的输出:
ID DOC_ID Count
---------------------
6 22 3
答案 0 :(得分:2)
在SQL Server 2012+中,您只需使用lag()
:
select t.*
from (select t.*, lag(count) over (partition by doc_id order by id) as prev_count
from t
) t
where prev_count <> count;
这在SQL Server 2008中更加痛苦。我建议apply
:
select t.*
from (select t.*, tprev.count as prev_count
from t cross apply
(select top (1) tprev.*
from t tprev
where tprev.doc_id = t.doc_id and tprev.id < t.id
order by tprev.id desc
) tprev
) t
where prev_count <> count;
此版本不需要子查询。我只是把它放在那里,这样你就可以看到两个查询之间的关系。这也适用:
select t.*
from t cross apply
(select top (1) tprev.*
from t tprev
where tprev.doc_id = t.doc_id and tprev.id < t.id
order by tprev.id desc
) tprev
where tprev.count <> t.count;
我还可以补充一点,如果您知道计数永远不会改变,那么您可以使用聚合获得每个计数的第一个id
:
select doc_id, count, min(id) as min(id)
from t
group by doc_id, count;
在许多情况下,这将比apply
版本更快(尽管lag()
通常会获得最佳效果)。