SQL Server返回字段更改的行

时间:2015-12-29 14:54:45

标签: sql sql-server record

我有一个包含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,但它没有按顺序插入,因为记录不在表中。我没有运气就做了大量的搜索。任何帮助将不胜感激。

3 个答案:

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

Example at SQL Fiddle.