SQL - 将行更改与最新和上一个条目进行比较

时间:2016-08-24 21:16:36

标签: sql-server

我正在尝试找到比较单个表中多个条目的最优雅方式。我们有一个表来保存审计数据,但它只是说明了当前的值。我想回顾一下这个相同对象的条目,看它是否有所不同。这是一个示例表模式:

ObjectID         Value            Timestamp
a                 granted          08/24/2016 17:56:59
b                 unset            08/24/2016 12:17:59
b                 unset            08/24/2016 11:17:45
a                 unset            08/23/2016 07:56:59
a                 deny             08/23/2016 20:12:59
b                 deny             08/22/2016 05:45:59

我试图找到最近的a,b与之前的a,b不同。在上面的示例中,我会发现第一个更改为unset->授予,最后一个b来自deny-> unset。

我想我必须做一个子查询并选择最新的行并比较该值。认为可能有更好的方法。

1 个答案:

答案 0 :(得分:0)

也许这可以帮助

Declare @Table table (ObjectID varchar(25), Value varchar(25), Timestamp Datetime)
Insert into @Table values 
('a','granted','08/24/2016 17:56:59'),
('b','unset','08/24/2016 12:17:59'),
('b','unset','08/24/2016 11:17:45'),
('a','unset','08/23/2016 07:56:59'),
('a','deny','08/23/2016 20:12:59'),
('b','deny','08/22/2016 05:45:59')
Declare @XML xml
Set @XML = (Select * from @Table for XML RAW)

;with cteBase as (
    Select ObjectID     = r.value('@ObjectID','varchar(25)') 
          ,Timestamp    = r.value('@Timestamp','datetime')
          ,Item         = Attr.value('local-name(.)','varchar(max)')
          ,Value        = Attr.value('.','varchar(max)')
    From @XML.nodes('/row') AS A(r)
    Cross Apply A.r.nodes('./@*[local-name(.)!="ObjectID"]') AS B(Attr)
)
,cteExt as (Select *,LastValue =Lag(Value) over (Partition By ObjectID,Item Order by Timestamp) From cteBase)
Select ObjectID
      ,Item
      ,Before=LastValue
      ,After =Value
      ,Timestamp
 From  cteExt 
 Where Value<>LastValue and LastValue is not null
   and Item not in ('Timestamp')
 Order By ObjectID,Timestamp

返回

ObjectID    Item    Before  After   Timestamp
a           Value   unset   deny    2016-08-23 20:12:59.000
a           Value   deny    granted 2016-08-24 17:56:59.000
b           Value   deny    unset   2016-08-24 11:17:45.000