为没有记录的月份中的几天创建 'Empty' 条记录
Creating 'Empty' Records for Days of the Month Without Records
我有一个非常简单的 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
6 月的某些日子在 table_a
中不存在,因此显然没有加入 table_b
。为这些未表示的日期创建记录并将占位符(例如 'EMPTY')分配给它们的 'status' 列的最佳方法是什么?这甚至可以使用纯 SQL 来完成吗?
基本上,您需要 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;
使用sargableWHERE
条件。您所拥有的不能在 date
上使用普通索引,并且必须默认为更昂贵的顺序扫描。 (我的最终查询中没有更多的 WHERE
条件。)
另外:不要使用基本类型名称(和标准 SQL 中的保留字)date
作为标识符。
相关(第2章):
- PostgreSQL: running count of rows for a query 'by minute'
我有一个非常简单的 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
6 月的某些日子在 table_a
中不存在,因此显然没有加入 table_b
。为这些未表示的日期创建记录并将占位符(例如 'EMPTY')分配给它们的 'status' 列的最佳方法是什么?这甚至可以使用纯 SQL 来完成吗?
基本上,您需要 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;
使用sargableWHERE
条件。您所拥有的不能在 date
上使用普通索引,并且必须默认为更昂贵的顺序扫描。 (我的最终查询中没有更多的 WHERE
条件。)
另外:不要使用基本类型名称(和标准 SQL 中的保留字)date
作为标识符。
相关(第2章):
- PostgreSQL: running count of rows for a query 'by minute'