Reputation: 443
I have two tables I am looking to join by their dates:
table 1: reference
| date |
| -------------- |
| 2018-01-01 |
| 2018-01-02 |
| 2018-01-03 |
| 2018-01-04 |
| 2018-01-05 |
| 2018-01-06 |
| 2018-01-07 |
| 2018-01-08 |
| 2018-01-09 |
| 2018-01-10 |
table 2: events
| id | date |
| -- | ---------- |
| aa | 2018-01-03 |
| bb | 2018-01-05 |
| cc | 2018-01-08 |
I am looking to join the two by their date fields to achieve the following results:
| id | reference date | event date |
| -- | -------------- | ---------- |
| aa | 2018-01-03 | 2018-01-03 |
| aa | 2018-01-04 | 2018-01-03 |
| bb | 2018-01-05 | 2018-01-05 |
| bb | 2018-01-06 | 2018-01-05 |
| bb | 2018-01-07 | 2018-01-05 |
| cc | 2018-01-08 | 2018-01-08 |
| cc | 2018-01-09 | 2018-01-08 |
| cc | 2018-01-10 | 2018-01-08 |
i.e for each event id, the reference date starts at the earliest event date for that id and ends when the next id kicks in. ( I hope i explained it well).
the code below works if I only have one event with one date. but with multiple events and start dates, it falls apart.
select
events.id,
reference.date,
events.date
from events
join reference on
reference.date >= events.date
Upvotes: 0
Views: 2395
Reputation: 272106
If you have access to window functions and CTEs you can simply use LEAD
:
WITH cte AS (
SELECT id, date, LEAD(date, 1) OVER (ORDER BY date) AS end_date
FROM events
)
SELECT cte.id, reference.date AS reference_date, cte.date AS event_date
FROM cte
INNER JOIN reference ON reference.date >= cte.date
AND (reference.date < cte.end_date OR cte.end_date IS NULL)
Upvotes: 1
Reputation: 1269803
Use a correlated subquery:
select r.*,
(select e.id
from events e
where e.date <= r.date
order by e.date desc
fetch first 1 row only
) as event_date,
(select e.date
from events e
where e.date <= r.date
order by e.date desc
fetch first 1 row only
) as event_date
from reference e;
Note that this uses ANSI-standard syntax. The syntax for returning a single row could vary by database.
Many databases also support lateral joins and/or cross apply
which simplifies the subqueries.
Upvotes: 0