Join a count query on a generate_series in postgres and also retrieve Null-values as “0”
我想得到的是每月从generate_series开始的统计数据以及每个月计算的id的总和。 这个SQL适用于PostgreSQL 9.1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | SELECT (to_char(serie,'yyyy-mm')) AS YEAR, SUM(amount)::INT AS eintraege FROM ( SELECT COUNT(mytable.id) AS amount, generate_series::DATE AS serie FROM mytable RIGHT JOIN generate_series( (SELECT MIN(date_from) FROM mytable)::DATE, (SELECT MAX(date_from) FROM mytable)::DATE, INTERVAL '1 day') ON generate_series = DATE(date_from) WHERE version = 1 GROUP BY generate_series ) AS foo GROUP BY YEAR ORDER BY YEAR ASC; |
这是我的输出
1 2 3 | "2006-12" | 4 "2007-02" | 1 "2007-03" | 1 |
但我想得到的是这个输出(1月份的"0"值):
1 2 3 4 | "2006-12" | 4 "2007-01" | 0 "2007-02" | 1 "2007-03" | 1 |
因此,如果有一个月没有id,那么它应该被列出。
任何想法如何解决这个问题?
以下是一些示例数据:
1 2 3 4 5 6 7 8 9 10 11 12 | DROP TABLE IF EXISTS mytable; CREATE TABLE mytable(id BIGINT, version SMALLINT, date_from TIMESTAMP WITHOUT TIME zone); INSERT INTO mytable(id, version, date_from) VALUES ('4084036', '1', '2006-12-22 22:46:35'), ('4084938', '1', '2006-12-23 16:19:13'), ('4084938', '2', '2006-12-23 16:20:23'), ('4084939', '1', '2006-12-23 16:29:14'), ('4084954', '1', '2006-12-23 16:28:28'), ('4250653', '1', '2007-02-12 21:58:53'), ('4250657', '1', '2007-03-12 21:58:53') ; |
解开,简化和修复,它可能看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 | SELECT to_char(s.tag,'yyyy-mm') AS monat , COUNT(t.id) AS eintraege FROM ( SELECT generate_series(MIN(date_from)::DATE , MAX(date_from)::DATE , INTERVAL '1 day' )::DATE AS tag FROM mytable t ) s LEFT JOIN mytable t ON t.date_from::DATE = s.tag AND t.version = 1 GROUP BY 1 ORDER BY 1; |
db <>在这里小提琴
在所有噪音,误导性标识符和非常规格式中,实际问题隐藏在此处:
1 | WHERE version = 1 |
在正确使用
将该子句拉入
我简化了其他一些事情。
有关:
- 生成PostgreSQL中两个日期之间的时间序列