关于sql:在postgres中的generate_series上加入计数查询,并将Null值检索为“0”

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

在正确使用RIGHT [OUTER] JOIN的同时,您通过添加WHERE子句来取消该操作,该子句需要来自mytable的不同值 - 有效地将RIGHT JOIN转换为JOIN

将该子句拉入JOIN条件以使其工作。

我简化了其他一些事情。

有关:

  • 生成PostgreSQL中两个日期之间的时间序列