Search code examples
sqlsql-servert-sqlsql-server-2017

Get Previous Row but using Date, rather than Primary


I've got the below example data, and for each "Person" identifier, I'm trying to show the field valuese for the latest Row (EffectiveTo=NULL), and the one before it.

How could this be done while not having a primary key with the data to use?

Expected Output is:

enter image description here

enter image description here

Create Table #temp
(
    Person int,
    Amount money,
    DailyAmount money,
    EffectiveFrom datetime,
    EffectiveTo datetime NULL
)

insert into #temp
(
    Person,
    Amount,
    DailyAmount,
    EffectiveFrom,
    EffectiveTo
)
select
    1,
    450,
    64.28,
    '2018-03-15 00:00:00.000',
    '2020-06-17 00:00:00.000'
union all
select
    1,
    500,
    71.42,
    '2020-05-22 00:00:00.000',
    '2020-06-18 00:00:00.000'
union all
select
    1,
    93.75,
    13.39,
    '2020-06-19 00:00:00.000',
    NULL    
union all
select
    2,
    200,
    28.57,
    '2019-02-05 00:00:00.000',
    '2020-01-02 00:00:00.000'
union all
select
    2,
    300,
    42.85,
    '2020-01-03 00:00:00.000',
    NULL    

select * from #temp

Solution

  • Use LEAD() OVER () window function to get previous rows data

    WITH mydata
    AS (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY person ORDER BY EffectiveFrom DESC) rn,
                  LEAD(amount) OVER (PARTITION BY person ORDER BY EffectiveFrom DESC) Prev_amount, 
                  LEAD(DailyAmount) OVER (PARTITION BY person ORDER BY EffectiveFrom DESC) Prev_DailyAmount, 
                  LEAD(EffectiveFrom) OVER (PARTITION BY person ORDER BY EffectiveFrom DESC) Prev_Eff_From, 
                  LEAD(EffectiveTo) OVER (PARTITION BY person ORDER BY EffectiveFrom DESC) Prev_Eff_To
        FROM #temp
        )
    SELECT Person, Amount, DailyAmount, EffectiveFrom, EffectiveTo, Prev_amount, Prev_DailyAmount, Prev_Eff_From, Prev_Eff_To
    FROM mydata
    WHERE rn = 1
    

    Check Demo Here