0

我有以下查询:

SELECT created_at::DATE, count (*) 
FROM messages      
WHERE city = 'los angeles'     
GROUP BY created_at::DATE

效果很好。挑战在于,如果给定日期没有消息,那么它不会返回该日期的记录。如果在给定日期和今天之间的所有日子里没有消息,您如何使上述查询返回日期和 0 ?

在 PostgreSQL 8.3 中工作。

谢谢!

4

3 回答 3

2

典型的方法是有一个单独的日历表,其中包含所有日期,在日期列上左连接到您的表,然后使用某种 ifnull(x, 0) 语句[无论函数用于 PostgreSQL] 或 case 语句当日期的左连接返回 null 时返回 0 或不为 null 时返回 1。然后你可以做你的正常分组并使用 SUM(x) 而不是 count()。

于 2011-07-15T21:41:59.120 回答
2

听起来您需要一个包含您感兴趣的所有日期的表格,因为它可能包含不在您的消息表中的日期。如果您拥有或构建了此表,则与消息表保持连接,并依靠该表的列进行计数——它将返回 0,其中没有任何内容与连接匹配。

select d.created_at, count(m.messageId)
from possibleDates d
left join messages m
    on d.created_at = m.created_at
group by d.created_at
于 2011-07-15T21:44:36.097 回答
2

很多时候,当您想为系列中的缺失条目填充零时,PostgreSQL 中的答案涉及该generate_series函数。(在 Stackoverflow 上搜索很多类似的问题和答案。)在您的情况下,请使用以下内容:

SELECT ts::date AS date, coalesce(count, 0) AS count
FROM
  (SELECT created_at::date, count(*)
   FROM messages
   WHERE city = 'los angeles'
   GROUP BY created_at::date) AS m
  RIGHT JOIN
  (SELECT *
   FROM generate_series(timestamp '2011-07-01',
                        timestamp 'today',
                        interval '1 day')) AS series(ts)
  ON m.created_at = series.ts
ORDER BY 1;
于 2011-07-17T18:18:12.967 回答