【问题标题】:Creating 'Empty' Records for Days of the Month Without Records为没有记录的月份创建“空”记录
【发布时间】:2015-09-13 18:31:38
【问题描述】:

我有一个非常简单的 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 中不存在,因此显然没有加入table_b。为这些未表示的日期创建记录并为其“状态”列分配占位符(例如“空”)的最佳方法是什么?使用纯 SQL 甚至可以做到这一点吗?

【问题讨论】:

  • cd.date 处于非法引用中。请修正您的示例代码并提供 Postgres 版本和您的列 date 的数据类型。另外:table_b 总是有整天吗?
  • 已修复。 table_b 包含状态码,其中一个适用于table_a 中的每一天。
  • 数据类型?是date 还是timestamp
  • a.date 类型为date

标签: postgresql calendar


【解决方案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 作为标识符。

相关(第二章):

【讨论】:

    猜你喜欢
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 2019-04-17
    • 2012-08-15
    相关资源
    最近更新 更多