1

I have a very simpl postgres (9.3) query that looks like this:

SELECT a.date, b.status
FROM sis.table_a a
JOIN sis.table_b b ON a.thing_id = b.thing_id
WHERE EXTRACT(MONTH FROM a.date) = 06
AND EXTRACT(YEAR FROM a.date) = 2015

Some days of the month of June do not exist in table_a and thus are obviously not joined to table_b. What is the best way to create records for these not represented days and assign a placeholder (e.g. 'EMPTY') to their 'status' column? Is this even possible to do using pure SQL?

Preston
  • 172
  • 3
  • 10

1 Answers1

1

Basically, you need LEFT JOIN and it looks like you also need generate_series() to provide the full set of days:

SELECT d.date
     , a.date IS NOT NULL AS a_exists
     , COALESCE(b.status, 'status_missing') AS status
FROM (
   SELECT date::date
   FROM   generate_series('2015-06-01'::date
                        , '2015-06-30'::date
                        , interval '1 day') date
    ) d
LEFT   JOIN sis.table_a a USING (date)
LEFT   JOIN sis.table_b b USING (thing_id)
ORDER  BY 1;

Use sargable WHERE conditions. What you had cannot use a plain index on date and has to default to a much more expensive sequential scan. (There are no more WHERE conditions in my final query.)

Aside: don't use the basic type name (and reserved word in standard SQL) date as identifier.

Related (2nd chapter):

Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228