Sql server SQL-将行更改与最近和以前的条目进行比较

Sql server SQL-将行更改与最近和以前的条目进行比较,sql-server,Sql Server,我试图找到一种最优雅的方法来比较一个表中的多个条目。我们有一个保存审计数据的表,但它只说明当前值是什么。我想回顾一下这个相同对象的条目,看看它是否不同。以下是一个示例表架构: ObjectID Value Timestamp a granted 08/24/2016 17:56:59 b unset 08/24/2016 12:17:59 b

我试图找到一种最优雅的方法来比较一个表中的多个条目。我们有一个保存审计数据的表,但它只说明当前值是什么。我想回顾一下这个相同对象的条目,看看它是否不同。以下是一个示例表架构:

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有什么不同。在上面的例子中,我会发现第一个a从unset->grated更改,最后一个b从deny->unset更改

我想我必须做一个子查询,选择最新值之前的行,并比较值。我想可能有更好的办法。

也许这会有所帮助

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')


您应该添加您认为查询最重要的内容和预期结果。您的代码在哪里!到目前为止,您尝试了什么?为了让您开始,我发现使用带有行号和自连接的CTE可以优雅地解决许多类似的问题。您还应该添加您正在使用的SQL Server版本。较新版本的功能可以使这一点变得更容易,因此与版本的兼容性很重要,最佳答案可能因版本而异。
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