Home > Software engineering >  Get closest date with id and value Oracle
Get closest date with id and value Oracle

Time:07-29

I ran into a problem and maybe there are experienced guys here to help me figure it out: I have a table with rows:

ID VALUE DATE
2827 0 20.07.2022 10:40:01
490 27432 20.07.2022 10:40:01
565 189 20.07.2022 9:51:03
200 1 20.07.2022 9:50:01
731 0.91 20.07.2022 9:43:21
161 13004 19.07.2022 16:11:01

This table has a million records, there are about 1000 ID instances, only the date of the value change and, therefore, the value itself changes in them. When the value of the ID changes is added to this table:

ID | Tme the value was changed (DATE) | VALUE

My task is to get the all id's values closest to the input date.

I mean: if I input date "20.07.2022 10:00:00" I want to get each ID (1-1000) with rows "value, date" with last date before "20.07.2022 10:00:00":

ID VALUE DATE
2827 0 20.07.2022 9:59:11
490 27432 20.07.2022 9:40:01
565 189 20.07.2022 9:51:03
200 1 20.07.2022 9:50:01
731 0.91 20.07.2022 8:43:21
161 13004 19.07.2022 16:11:01

What query will be the most optimal and correct in this case?

CodePudding user response:

If you want the data for each ID with the latest change up to, but not after, your input date then you can just filter on that date, and use aggregate functions to get the most recent data in that filtered range:

select id,
  max(change_time) as change_time,
  max(value) keep (dense_rank last order by change_time) as value
from your_table
where change_time <= <your input date>
group by id

With your previous sample data, using midnight this morning as the input date would give:

select id,
  max(change_time) as change_time,
  max(value) keep (dense_rank last order by change_time) as value
from your_table
where change_time <= timestamp '2022-07-28 00:00:00'
group by id
order by id
ID CHANGE_TIME VALUE
1 2022-07-24 10:00:00 900
2 2022-07-22 21:51:00 422
3 2022-07-24 13:01:00 1
4 2022-07-24 10:48:00 67

and using midday today woudl give:

select id,
  max(change_time) as change_time,
  max(value) keep (dense_rank last order by change_time) as value
from your_table
where change_time <= timestamp '2022-07-28 12:00:00'
group by id
order by id
ID CHANGE_TIME VALUE
1 2022-07-24 10:00:00 900
2 2022-07-22 21:51:00 422
3 2022-07-28 11:59:00 12
4 2022-07-28 11:45:00 63
5 2022-07-28 10:20:00 55

db<>fiddle with some other input dates to show the result set changing.

  • Related