In MS SQL 2012, I have a table like such:
x
Key | Entity | Value | DateTime
-----------------------------------------------------------
10 A 800 1/1/2019 12:00:00 AM
08 A 800 1/1/2018 12:00:00 AM
06 A 700 1/1/2017 12:00:00 AM
04 A 725 1/1/2016 12:00:00 AM
09 B 550 1/1/2019 12:00:00 AM
07 B 400 1/1/2018 12:00:00 AM
05 B 400 1/1/2017 12:00:00 AM
03 B 375 1/1/2016 12:00:00 AM
I would like to return the date of change and the amount of change — from the last record where the value changed from the record before it.
Ideally, this:
Entity | ValueChange | DateofChange
------------------------------------------------
A 100 1/1/2018
B 150 1/1/2019
Entity A last changed on 1/1/2018 by 100, Entity B last changed on 1/1/2019 by 150
I’m thinking it’s going to be some combination of Lag and maybe this discussion: SQL: selecting rows where column value changed from previous row
But I’m very much a SQL beginner and have no formal training, and I appreciate any detail and extra explanations you can provide.
Thank you!
Advertisement
Answer
First with a CTE
which returns all the changes and then with NOT EXISTS
that returns the last change for each Entity
:
(Edited with the actual table and column names)
with cte as (
select t.hUnit UnitID, (t.cRent - tt.cRent) cRentChange, t.dtDate DateofChange
from unit_history t inner join unit_history tt
on
tt.hUnit = t.hUnit
and
tt.dtDate = (
select max(dtDate)
from unit_history
where hUnit = t.hUnit and dtDate < t.dtDate
)
where t.cRent <> tt.cRent
)
select c.* from cte c
where not exists (
select 1 from cte
where UnitID = c.UnitID and DateofChange > c.DateofChange
)
See the demo.
Results:
Entity | ValueChange | DateofChange
> :----- | ----------: | :------------------
> A | 100 | 01/01/2018 00:00:00
> B | 150 | 01/01/2019 00:00:00