我正在尝试使用我在此处找到的各种示例来构建查询,但到目前为止收效甚微:
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
。
答案 0 :(得分:1)
问题在于您对订单表中的字段进行了过滤,这违背了使用外部联接的目的。请在您的加入中包含该条件:
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;
答案 1 :(得分:0)
@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
返回的内容)强制转换为date
,然后才能转回timestamp
进行匹配hist_create
中的LEFT JOIN
。
相反,请创建一个timestamp
系列并直接匹配。仅转换为date
输出(或以to_char()
显示的任何方式格式化值)。使用EXPLAIN ANALYZE
进行测试,以验证其性能稍好一些。它还通过在timestamptz和日期/时间戳之间进行投射来最小化偷偷摸摸的角落错误。更多细节: