问题
我有一个生成日期表 (s),我想将其与另一个表 (d) 连接,该表是发生特定事件的日期列表。
表
Wednesday 23rd August 2017
Thursday 24th August 2017
Friday 25th August 2017
Saturday 26th August 2017
表 d
day_created -------------------------------- count
Thursday 24th August 2017 ---------------- 45
Saturday 26th August 2017 ---------------- 32
我想显示没有发生事件的行,如果我只有表 d,我就不能这样做。
我想要的东西看起来像:
day_created -------------------------------- count
Wednesday 23rd August --------------------- 0
Thursday 24th August 2017 ---------------- 45
Friday 25th August 2017 ------------------ 0
Saturday 26th August 2017 ---------------- 32
我试过按如下方式使用左连接进行连接:
SELECT day_created, COUNT(d.day_created) as total_per_day
FROM
(SELECT date_trunc('day', task_1.created_at) as day_created
FROM task_1
)
d
LEFT JOIN (
SELECT (generate_series('2017-05-01', current_date, '1 day'::INTERVAL)) as standard_date
)
s
ON d.day_created=s.standard_date
GROUP BY d.day_created
ORDER BY day_created DESC;
我没有收到错误,但是连接不起作用(即它不返回计数为空的日期)。它返回的是表 d 中的日期和计数,但不是出现次数为 0 的中间日期。
我一直在兜圈子,并且明白我需要制作表 s
(我认为!)左表,但作为新手,我对语法感到困惑。
这一切都在 PostgreSQL 9.5.8 中。
最佳答案
基本上,您的 LEFT JOIN
倒退了。这应该可以工作,还有一些其他的简化和性能优化:
SELECT s.standard_date, COUNT(d.day_created) AS total_per_day
FROM generate_series('2017-05-01', current_date, interval '1 day') s(standard_date)
LEFT JOIN task_1 d ON d.day_created >= s.standard_date
AND d.day_created < s.standard_date + interval '1 day'
GROUP BY 1
ORDER BY 1;
这计算 d
中的行,就像您评论的那样。不求和值。
请注意 generate_series()
仍会返回 timestamp with time zone
,即使您将 date
值传递给它也是如此。您可能希望转换为 date
或使用 to_char()
格式化以显示在外部 SELECT
中。 (而是按原始时间戳 值 分组和排序,而不是格式化字符串。)
根据实际未公开的表定义,根据当前时区设置,可能存在极端情况。
相关:
关于sql - 左连接嵌套选择和聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45898000/