Home > Software engineering >  Retrieve records from versioned table
Retrieve records from versioned table

Time:02-04

this sql case has been troubling me for a while and I wanted to ask here what other folks think.

I have a table user who owns vehicles, but the same vehicle maybe owned by multiple user over time, there is another column called effective_date which tells from what day this is owning is effective. Two driver doesn't own the same vehicle, but records are versioned, meaning we can check who owned this vehicle 2 years ago, or 5 years ago using effective date.

Table has following columns,

id, version, name, vehicle_id, effective_date. Every change to this table is versioned

Now there is another table called accidents which tells what accident with vehicle and when, not versioned

it has id, description, vehicle_id, acc_date

Now I am trying to select all accidents and who caused the accident. Inner join doesn't work here, What I do is select all rows from accident table and run sub query for each row and find the user's id and version that was responsible for the cause. This will be super slow and I am looking for more performant way of organizing the date or constructing a query. Right now it runs a subquery for every row it selects from accident table, because each row has different accident date. I am ok doing few queries if there is easy way of doing within a single query.

Example user table

id version name vehicle_id effective_date
1 1 A 1 01/10/2021
1 2 A 2 02/10/2021
2 1 B 1 03/10/2021
2 2 B 2 04/10/2021

accident:

id description vehicle_id acc_date
1 hit1 1 03/5/2021
2 hit2 1 03/15/2021

Result:

user_id user_version acc_id vehicle_id acc_date
1 1 1 1 03/5/2021
2 1 2 1 03/15/2021

thanks for your help

CodePudding user response:

Select a.id as user_id, a.version 
as user_version,
b.id as acc_id, a.vehicle_id,
acc_date from user a
Inner Join
Accident b on
a.vehicle_id = b.vehicle_id

CodePudding user response:

To get the latest user at the time of the accident you can use ROW_NUMBER() sorting by descending effective_date. With this ordering the first user listed for each accident is the responsible one.

For example:

select *
from (
  select *, 
    row_number() over(partition by u.vehicle_id
                      order by effective_date desc) as rn
  from user u
  join accident a on a.vehicle_id = u.vehicle_id
  where u.effective_date <= a.acc_date
) x
where rn = 1
  •  Tags:  
  • Related