我有一个非常简单的postgres(9.3)查询,如下所示:
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
table_a
中不存在6月份的某些日子,因此显然没有加入table_b
。为这些未表示的日期创建记录的最佳方法是什么,并将占位符(例如“EMPTY”)分配给其“状态”列?这甚至可以使用纯SQL吗?
答案 0 :(得分:1)
基本上,您需要LEFT JOIN
,看起来您还需要generate_series()
来提供完整的日期:
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;
使用sargable WHERE
条件。您所拥有的内容无法在date
上使用普通索引,并且必须默认为更昂贵的顺序扫描。 (我的最终查询中没有WHERE
个条件。)
除此之外:不要使用基本类型名称(标准SQL中的保留字)date
作为标识符。
相关(第2章):