检查SQL中的table是否连续出现两个不同的值?
Check if two different values appear successively in a table in SQL?
有一个table看起来像这样(有更多的列,但与查询无关):
DocumentId | DocumentStateId | TransitionMoment
111222 -2 2016-04-21
111222 -1 2016-04-22
111222 -7 2016-04-23
111222 -5 2016-04-24
111222 -6 2016-04-25
111222 -1 2016-04-26
333141 -2 2016-05-01
333141 -7 2016-05-09
333141 -6 2016-05-10
333141 -3 2016-05-15
777525 -1 2016-02-10
777525 -6 2016-02-10
777525 -7 2016-02-10
777525 -5 2016-02-10
777525 -2 2016-02-10
我有哪些选项可以检查文档是否连续从状态“-7”变为状态“-6”(中间没有通过其他状态转换)?在示例文档中。 33141.
提前致谢!
在 SQL Server 2012+ 中,您只需使用 lag()
。在 SQL Server 2005 中,您可以使用 apply
:
select t.*
from t cross apply
(select top 1 t2.*
from t t2
where t2.documentid = t.documentid and
t2.transitionmoment > t.transitionmoment
order by t2.transitionmoment desc
) tnext
where t.DocumentStateId = -7 and
tnext.DocumentStateId = -6;
使用 LEAD():
WITH CTE AS
(
SELECT
DocumentId, DocumentStateId, TransitionMoment,
LEAD(DocumentStateId) OVER (ORDER BY TransitionMoment) NextSIDVal,
LEAD(DocumentId) OVER (ORDER BY DocumentId) NextDIDVal
FROM Table
)
SELECT DocumentId, DocumentStateId, TransitionMoment FROM CTE
WHERE DocumentStateId = -7 AND NextSIDVal = -6
AND DocumentId = NextDIDVal
使用ROW_NUMBER():
WITH CTE AS
(
SELECT
DocumentId, DocumentStateId, TransitionMoment, ROW_NUMBER() OVER (ORDER BY TransitionMoment) RowVal
FROM Table
)
SELECT x.DocumentId, x.DocumentStateId, x.TransitionMoment
FROM CTE x
JOIN CTE y
ON x.RowVal + 1 = y.RowVal
WHERE x.DocumentStateId = -7 AND y.DocumentStateId = -6
AND x.DocumentId = y.DocumentId
有一个table看起来像这样(有更多的列,但与查询无关):
DocumentId | DocumentStateId | TransitionMoment
111222 -2 2016-04-21
111222 -1 2016-04-22
111222 -7 2016-04-23
111222 -5 2016-04-24
111222 -6 2016-04-25
111222 -1 2016-04-26
333141 -2 2016-05-01
333141 -7 2016-05-09
333141 -6 2016-05-10
333141 -3 2016-05-15
777525 -1 2016-02-10
777525 -6 2016-02-10
777525 -7 2016-02-10
777525 -5 2016-02-10
777525 -2 2016-02-10
我有哪些选项可以检查文档是否连续从状态“-7”变为状态“-6”(中间没有通过其他状态转换)?在示例文档中。 33141.
提前致谢!
在 SQL Server 2012+ 中,您只需使用 lag()
。在 SQL Server 2005 中,您可以使用 apply
:
select t.*
from t cross apply
(select top 1 t2.*
from t t2
where t2.documentid = t.documentid and
t2.transitionmoment > t.transitionmoment
order by t2.transitionmoment desc
) tnext
where t.DocumentStateId = -7 and
tnext.DocumentStateId = -6;
使用 LEAD():
WITH CTE AS
(
SELECT
DocumentId, DocumentStateId, TransitionMoment,
LEAD(DocumentStateId) OVER (ORDER BY TransitionMoment) NextSIDVal,
LEAD(DocumentId) OVER (ORDER BY DocumentId) NextDIDVal
FROM Table
)
SELECT DocumentId, DocumentStateId, TransitionMoment FROM CTE
WHERE DocumentStateId = -7 AND NextSIDVal = -6
AND DocumentId = NextDIDVal
使用ROW_NUMBER():
WITH CTE AS
(
SELECT
DocumentId, DocumentStateId, TransitionMoment, ROW_NUMBER() OVER (ORDER BY TransitionMoment) RowVal
FROM Table
)
SELECT x.DocumentId, x.DocumentStateId, x.TransitionMoment
FROM CTE x
JOIN CTE y
ON x.RowVal + 1 = y.RowVal
WHERE x.DocumentStateId = -7 AND y.DocumentStateId = -6
AND x.DocumentId = y.DocumentId