我有一个包含3个值的表。
ID AuditDateTime UpdateType
12 12-15-2015 18:09 1
45 12-04-2015 17:41 0
75 12-21-2015 04:26 0
12 12-17-2015 07:43 0
35 12-01-2015 05:36 1
45 12-15-2015 04:35 0
我尝试仅根据ID返回UpdateType
已从AuditDateTime
更改的记录。因此,在此示例中,ID 12从12-15条目更改为12-17条目。我希望该记录返回。将有多个ID 12的实例,并且我需要返回所有记录,其中ID UpdateType
已从之前的条目更改。我尝试添加row_number
,但它没有按顺序插入,因为记录不在表中。我没有运气就做了大量的搜索。任何帮助将不胜感激。
答案 0 :(得分:3)
通过使用CTE,可以根据AuditDateTime的顺序找到以前的记录
WITH CTEData AS
(SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY AuditDateTime) [ROWNUM], *
FROM @tmpTable)
SELECT A.ID, A.AuditDateTime, A.UpdateType
FROM CTEData A INNER JOIN CTEData B
ON (A.ROWNUM - 1) = B.ROWNUM AND
A.ID = B.ID
WHERE A.UpdateType <> B.UpdateType
Inner Join返回到CTE将在一个查询中提供当前记录(表别名A)和上一行(表别名B)。
答案 1 :(得分:0)
这应该做你想做的事我相信
SELECT
T1.ID,
T1.AuditDateTime,
T1.UpdateType
FROM
dbo.My_Table T1
INNER JOIN dbo.My_Table T2 ON
T2.ID = T1.ID AND
T2.UpdateType <> T1.UpdateType AND
T2.AuditDateTime < T1.AuditDateTime
LEFT OUTER JOIN dbo.My_Table T3 ON
T3.ID = T1.ID AND
T3.AuditDateTime < T1.AuditDateTime AND
T3.AuditDateTime > T2.AuditDateTime
WHERE
T3.ID IS NULL
可替换地:
SELECT
T1.ID,
T1.AuditDateTime,
T1.UpdateType
FROM
dbo.My_Table T1
INNER JOIN dbo.My_Table T2 ON
T2.ID = T1.ID AND
T2.UpdateType <> T1.UpdateType AND
T2.AuditDateTime < T1.AuditDateTime
WHERE
NOT EXISTS
(
SELECT *
FROM
dbo.My_Table T3
WHERE
T3.ID = T1.ID AND
T3.AuditDateTime < T1.AuditDateTime AND
T3.AuditDateTime > T2.AuditDateTime
)
两个查询的基本要点是,您要查找前一行具有不同类型且两行之间不存在其他行的行(因此,它们是顺序的)。两个查询在逻辑上是相同的,但可能具有不同的性能。
此外,这些查询假设没有两行具有相同的审核时间。如果情况并非如此,那么您需要定义发生这种情况时的预期结果。
答案 2 :(得分:0)
您可以使用lag()
窗口函数查找同一ID
的上一个值。现在,您只能选择引入更改的行:
select *
from (
select lag(UpdateType) over (
partition by ID
order by AuditDateTime) as prev_updatetype
, *
from YourTable
) sub
where prev_updatetype <> updatetype