Reputation: 287
I'm having an issue with a postrgresql join. I might be approaching it incorrectly, but here's the scenario.
I have a table which contains two relevant columns: dates and months (along with other data). Each date should have the next 5 months associated with it, inclusive. This isn't always the case; I want to find when this isn't the case. Additionally, there is no guarantee that each date is in the table (for which there should be 5 months), but I have another table which contains these dates.
The table should contain (for one date):
However, due to many possibilities the table may only contain:
I have attempted to find the missing dates by generating a series for the expected dates and joining a series of months that should be associated with the date. I'm running into an issue because I need to join the tables on the two columns I need, so if one doesn't exist, it doesn't make it through the ON or WHERE clause.
I might need to approach this differently, but here is my current attempt.
SELECT
D.date, JOINMONTH::date, DT.month
FROM
day D
CROSS JOIN
generate_series(date_trunc('month', D.date),
date_trunc('month', D.date) + INTERVAL '4 months',
'1 month') AS JOINMONTH
LEFT JOIN
dates_table DT ON D.date = DT.date
AND JOINMONTH::date = DT.month
WHERE
D.date >= '2018-01-01';
What I would like to see:
EDIT: This db-fiddle gives my full query. I omitted some of the where clause because I thought it was irrelevant, but it seems to be part of the problem. With this in mind, my selected answer will solve my problem represented by this structure/query but @Gordon Linoff's answer is correct for the original question.
Upvotes: 0
Views: 743
Reputation: 287
SELECT D.date, JOINMONTH::date, DT.month
FROM day D
CROSS JOIN LATERAL
generate_series(date_trunc('month', D.date),
date_trunc('month', D.date) + INTERVAL '4 months',
'1 month') AS JOINMONTH
LEFT JOIN dates_table DT
ON D.date = DT.date
AND JOINMONTH::date = DT.month
AND DT.source = 'S1' AND
DT.tf = TRUE
WHERE
D.date = '2018-11-02';
I needed to move parts of my where clause into the join itself.
Upvotes: 0
Reputation: 1269493
Is this what you are looking for?
SELECT D.date, JOINMONTH::date, DT.month
FROM day D CROSS JOIN LATERAL
generate_series(date_trunc('month', D.date),
date_trunc('month', D.date) + INTERVAL '4 months',
'1 month') AS JOINMONTH LEFT JOIN
dates_table DT
ON GD.date = DT.date AND JOINMONTH::date = DT.month
WHERE D.date >= '2018-01-01' AND DT.date IS NULL;
Upvotes: 1