2015-06-26 68 views
1

我有一个非常SIMPL的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。为这些没有代表的日子创建记录并为其“状态”列指定一个占位符(例如'EMPTY')的最佳方式是什么?这甚至有可能使用纯SQL?

+0

可能重复(http://stackoverflow.com/questions/5905064/mark-non-连续日期范围) –

+0

'cd.date'是非法引用。请修复您的示例代码并提供Postgres版本和您的列'date'的数据类型。另外:'table_b'总是有天吗? –

+0

固定。 Table_b包含状态码,其中一个适用于table_a中的每一天。 – Preston

回答

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; 

使用sargableWHERE条件。你有什么不能在date上使用普通索引,并且必须默认为更昂贵的顺序扫描。 (在我的最终查询中没有更多的WHERE条件。)

另外:不要使用基本类型名称(和标准SQL中的保留字)date作为标识符。

相关(第2章):马克非连续的日期范围]的