SQL Server Audit表中的唯一连续值

时间:2017-02-17 16:43:03

标签: sql sql-server sql-server-2008

我们的数据库包含一个审计表,每次更改项目费用值时都会添加一个新行。不幸的是,当实际上没有从先前值发生变化时,它也可以添加行。我的任务是提取这些数据,以便我们可以看到项目值如何随时间变化,但是我想从输出中排除任何连续的重复行。非连续的重复值非常精细,因为它们反映了项目上下值

简化示例数据

ID 1, DateCreated 2016-03-02, Value 0
ID 2, DateCreated 2016-03-04, Value 0
ID 3, DateCreated 2016-03-05, Value 20
ID 4, DateCreated 2016-03-06, Value 50
ID 5, DateCreated 2016-03-07, Value 50
ID 6, DateCreated 2016-03-08, Value 20
ID 7, DateCreated 2016-03-10, Value 20
ID 8, DateCreated 2016-03-11, Value 0

根据这些数据,我希望看到以下结果

ID 1, DateCreated 2016-03-02, Value 0
ID 3, DateCreated 2016-03-05, Value 20
ID 4, DateCreated 2016-03-06, Value 50
ID 6, DateCreated 2016-03-08, Value 20
ID 8, DateCreated 2016-03-11, Value 0

我尝试过使用Row_Number分区功能虽然这会将不连续的行组合在一起

SELECT  *
FROM
(SELECT id, 
DateCreated, 
Value
,ROW_NUMBER() OVER (PARTITION BY Value ORDER BY id) AS rn
FROM tblTest) AS Test
WHERE Test.rn = 1

ID 1, DateCreated 2016-03-02, Value 0
ID 3, DateCreated 2016-03-05, Value 20
ID 4, DateCreated 2016-03-06, Value 50

因此,我想知道是否有人对我如何做到这一点有任何建议?我正在使用的SQL版本是2008R2 Express,但它不会是升级到更新版本的showstopper

2 个答案:

答案 0 :(得分:1)

您可以使用行数方法的差异将连续值分类为组。然后使用row_number函数获取每个组中的第一行。

运行最里面的查询,以查看如何根据连续值(按datecreated排序)分配组值。

select id,datecreated,value 
from (select *,row_number() over(partition by grp order by datecreated) as rn
      from (select *
            ,row_number() over(order by datecreated) 
            - row_number() over(partition by value order by datecreated) as grp
            from t
           ) x
      ) y
where rn = 1

在2012及更高版本中,您可以使用FIRST_VALUE函数获取每个组中的第一个值。

select distinct 
 first_value(id) over(partition by grp order by datecreated) as id
,first_value(datecreated) over(partition by grp order by datecreated) as datecreated
,value
from (select *
      ,row_number() over(order by datecreated) 
      - row_number() over(partition by value order by datecreated) as grp
      from t) x

答案 1 :(得分:0)

将ORDER BY添加到内部查询中,并在较小程度上添加外部查询。让它看起来像这样......

SELECT  *
FROM
    (SELECT id, 
        DateCreated, 
        Value,
        ROW_NUMBER() OVER (PARTITION BY Value ORDER BY id) AS rn
    FROM tblTest
    ORDER BY id) AS Test
WHERE Test.rn = 1
ORDER BY Test.id

这应该会返回您正在寻找的结果。