Quantcast
Channel: CodeSection,代码区,SQL Server(mssql)数据库 技术分享 - CodeSec
Viewing all articles
Browse latest Browse all 3160

Unique SQL Server Check Array Values

$
0
0

Our database contains an audit table which gets a new row added every time a projects fee value is changed. Unfortunately it can also get rows added when there is not actually a change from the prior values. I have been tasked with extracting this data so we can see how a projects value has changed over time however I would like to exclude any consecutive duplicate rows from the output. Duplicate values that are non-consecutive are perfectly fine as they reflect a project going up and down in value

Simplified Example Data

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

Based on this data, I would expect to see the following result

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

I have tried using the Row_Number Partition feature though this is grouping together rows that are not consecutive

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

I therefore wonder if anyone has any advice as to how I may do this? The SQL version I am using is 2008R2 Express however it would not be a showstopper to upgrade to a newer version

You can use the difference of row numbers approach to classify consecutive values into groups. Then get the first row in each group using the row_number function.

Run the innermost query to see how group values are assigned based on consecutive values (ordered by datecreated) being the same.

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

In versions 2012 and beyond, you can use the FIRST_VALUE function to get the first value in each group.

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


Viewing all articles
Browse latest Browse all 3160

Trending Articles