问题
I have a table in a SQL Server database which stores historical data on daily basis. The structure is shown below:
UploadDate TypeID Value1 Value2
-------------------------------------------
2012-01-08 1 NEG 1998-02-05
2012-01-08 2 NEG 1999-02-09
2012-01-08 3 STABLE 1997-02-06
2012-02-08 1 NEG 1998-02-05
2012-02-08 2 NEG 1999-02-09
2012-03-08 1 POS 2012-03-08
2012-03-08 2 STABLE 2012-01-08
As you can see above for the TypeID 1 & 2, Value1 and Value2 has changed on 2012-03-08
My requirement is such that I have to show only those rows which have changed from previous values.
In this case since TypeID 1 & 2 have changed than it should show the current and most nearest previous value. And for TypeID 3 since it has not changed, it will will only show the most current values. The result set would look something like below:
UploadDate TypeID Value1 Value2
-------------------------------------------
2012-01-08 3 STABLE 1997-02-06
2012-02-08 1 NEG 1998-02-05
2012-02-08 2 NEG 1999-02-09
2012-03-08 1 POS 2012-03-08
2012-03-08 2 STABLE 2012-01-08
Any idea how I can tackle this using SQL?
回答1:
Uninspired version uses self-join on ordered set to check the value of chronologically previous row of the same typeid. If there is no previous row or values are different the row is output.
; with numbered as (
select *,
row_number() over (order by typeid, uploaddate) rn
from table1
)
select n1.*
from numbered n1
left join numbered n2
on n1.TypeID = n2.TypeID
and n1.rn + 1 = n2.rn
where (n2.rn is null
or n1.value1 <> n2.value1
or n1.value2 <> n2.value2)
order by typeid, uploaddate
Here is Sql Fiddle with example.
UPDATE: another variant which does not require self-join but does require group by. Each timeline of same typeid, value1 and value2 are given unique group_number which is used later to extract max(uploaddate) for the group.
; with numbered as (
select *,
row_number() over (order by typeid, uploaddate)
- row_number() over (partition by typeid, value1, value2
order by uploaddate) group_number
from table1
)
select max(uploaddate) uploaddate, typeid, value1, value2
from numbered
group by typeid, value1, value2, group_number
order by typeid, uploaddate
Another Sql Fiddle.
来源:https://stackoverflow.com/questions/11854673/sql-query-to-show-change-history-of-data