I have two tables:
dates:
date |
---|
2024-01-01 |
2024-01-02 |
2024-01-03 |
2024-01-04 |
2024-01-05 |
actual:
business_date | id |
---|---|
2024-01-01 | 1 |
2024-01-02 | 2 |
2024-01-04 | 4 |
2024-01-05 | 5 |
I want to join these tables on the condition date = business_date, but in the case where there’s no match on dates it would get the record of the previous date. So resulting table would look like:
business_date | id | date |
---|---|---|
2024-01-01 | 1 | 2024-01-01 |
2024-01-02 | 2 | 2024-01-02 |
2024-01-02 | 2 | 2024-01-03 |
2024-01-04 | 4 | 2024-01-04 |
2024-01-05 | 5 | 2024-01-05 |
How would I achieve this?
2
Answers
An example of
full outer join
withcoalesce()
andlag()
window function: demoid
if there’s a matchingbusiness_date
.coalesce()
, if it finds that the date doesn’t have anid
, it switches tolag(id)over w1
, which looks back at the previous date and takes it from that.business_date
null
.If that’s a gaps-and-islands problem and you’d like
lag()
to skip over nulls until it finds the most recentid
– making that not just the previous date but rather the most recent with anid
– that’d be askip nulls
clause that’s currently missing from Postgres. Luckily, you can emulate it:Aggregate functions can be used as window functions, and those have a
filter
clause you can use to skipnull
values. The window specification tells it to order them so that the most recent non-null
ends up first in the array, which you then take witharr[1]
. If you do it often, you can declare a nicer-looking aggregate function like that.Or…
Demo : https://dbfiddle.uk/tzjjhZJu