在这种特定情况下如何显示空行?

How to display empty rows in this specific case?

我正在尝试使用我在此处找到的各种示例来构建查询,但到目前为止收效甚微:

SELECT count(o.hist_create) AS daily_count, d.day AS date_column 
FROM  (
SELECT day::date FROM generate_series(
(SELECT hist_create FROM orders ORDER BY hist_create LIMIT 1),
CURRENT_TIMESTAMP, 
interval '1 day')day)d 
LEFT JOIN orders o ON date_trunc('day', o.hist_create) = d.day
WHERE o.customerId = '1234'
GROUP  BY d.day 
ORDER  BY d.day;

所以在这里我想每天计算特定客户从第一个订单的时间戳到今天的订单,虽然这有效,但它不会获取没有该客户订单的日期.我想看到类似的内容:

number | date 
     15| 06-12-2017 
     0 | 07-12-2017
     9 | 08-12-2017
     11| 09-12-2017

但我得到:

number | date 
     15| 06-12-2017 
     9 | 08-12-2017
     11| 09-12-2017

我认为加入会解决这个问题,而且这个解决方案似乎对其他人有效,但在以我的方式定位客户时可能不是这样?

hist_create的数据类型为timestamp

问题是您在订单 table 的字段上进行过滤,这违背了使用外部联接的目的。改为在您的加入中包含该条件:

SELECT count(o.hist_create) AS daily_count, d.day AS date_column 
FROM  (
SELECT day::date FROM generate_series(
(SELECT hist_create FROM orders ORDER BY hist_create LIMIT 1),
CURRENT_TIMESTAMP, 
interval '1 day')day)d 
LEFT JOIN orders o ON date_trunc('day', o.hist_create) = d.day AND o.customerId = '1234'

GROUP  BY d.day 
ORDER  BY d.day;

@fauxmosapien 指出了 LEFT JOIN.

的主要问题

但由于您的列 hist_create 的数据类型为 timestamp,查询可以像这样进一步改进:

SELECT count(o.hist_create) AS daily_count, d.day::date AS date_column 
FROM  (
   SELECT generate_series(min(hist_create), now()::timestamp, interval '1 day') AS day
   FROM   orders
   ) d
LEFT   JOIN orders o ON date_trunc('day', o.hist_create) = d.day
                    AND o.customerId = '1234'  -- why is the number quoted?
GROUP  BY d.day 
ORDER  BY d.day;

您的原始查询生成一系列 timestamptz 值(因为那是 CURRENT_TIMESTAMP returns)在必须转换回 [=13 之前转换为 date =] 匹配 LEFT JOIN.

中的 hist_create

相反,创建一个 timestamp 系列并直接匹配。仅转换为 date 用于输出(或以任何您喜欢的方式格式化值以使用 to_char() 显示)。使用 EXPLAIN ANALYZE 进行测试以验证其性能是否稍好。它还通过在 timestamptz 和日期/时间戳之间进行转换来最大程度地减少偷偷摸摸的角落案例错误。更多详情:

  • Generating time series between two dates in PostgreSQL