sql - 获取每天创建的条目数

标签 sql postgresql aggregate-functions generate-series

假设我有一个这样的搜索查询:

SELECT COUNT(id), date(created_at)
FROM entries
WHERE date(created_at) >= date(current_date - interval '1 week')
GROUP BY date(created_at)

如你所知,例如我得到这样的结果:

count | date
  2   |  15.01.2014
  1   |  13.01.2014
  9   |  09.01.2014

但我没有得到没有创建条目的星期几。

我怎样才能得到这样的搜索结果,包括没有创建条目的日子?

count | date
  2   |  15.01.2014
  0   |  14.01.2014
  1   |  13.01.2014
  0   |  12.01.2014
  0   |  11.01.2014
  0   |  10.01.2014
  9   |  09.01.2014

最佳答案

SELECT day, COALESCE(ct, 0) AS ct
FROM  (SELECT now()::date - d AS day FROM generate_series (0, 6) d) d  -- 6, not 7
LEFT   JOIN (
   SELECT created_at::date AS day, count(*) AS ct 
   FROM   entries
   WHERE  created_at >= date_trunc('day', now()) - interval '6d'
   GROUP  BY 1
   ) e USING (day);

使用 sargable WHERE 条件的表达式,因此 Postgres 可以在 created_at 上使用普通索引。性能远比其他所有重要。

要涵盖一周(包括今天),请从“今天”开始减去 6 天,而不是 7 天。 或者,将周移动 1 以结束“昨天”,因为“今天”显然还不完整。

假设 id 被定义为 NOT NULLcount(*) 等同于 count(id) ,但速度稍快。见:

A CTE简单情况不需要。会更慢、更冗长。

先聚合,后加入。这样更快。

now() 是 Postgres 对标准 SQL CURRENT_TIMESTAMP 的简短语法(你也可以使用)。见:

这应该是最短最快的查询。使用 EXPLAIN ANALYZE 进行测试。

相关:

关于sql - 获取每天创建的条目数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29362384/

相关文章:

sql - 使用 COUNT(*) 或 SELECT * 是个好主意吗?

android - 平板电脑上的 Postgresql 服务器?

debugging - 在 Postgresql 中,如何调试删除级联后发生的错误?

mysql - SQL 仅选择列上具有最大值的行

sql - 创建全局声明

MySQL插入记录

postgresql - Postgres : narrowing trigger scope

sql - 当多个条件满足时,如何将它们分组计算平均值

SQL 帮助 MAX 查询

sql - postgresql 中的 IF-THEN-ELSE 语句