2012-11-16 35 views
7

我想得到的是統計每個月從一個generate_series和計數的ID在每個月的總和。這個SQL工作在PostgreSQL的9.1:加入postgres中generate_series的計數查詢,也檢索空值爲「0」

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; 

這是我的輸出

"2006-12" | 4 
"2007-02" | 1 
"2007-03" | 1 

但我想是這樣的輸出(一月 「0」 值):

"2006-12" | 4 
"2007-01" | 0 
"2007-02" | 1 
"2007-03" | 1 

所以如果有一個沒有ID的月份,它應該被列出。 任何想法如何解決這個問題?

下面是一些樣本數據:

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

一如既往,mytable表的定義應該在你的問題中。一些示例值與它會一起膨脹。 –

回答

16

解開,簡化和固定,它可能是這樣的:

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; 

在所有的噪音,誤導性標識和非常規形式的實際問題是隱藏在這裏:

WHERE version = 1 

雖然您正確使用了RIGHT JOIN,您通過添加一條WHERE子句來排除這種努力,該子句需要從mytable開始的不同值 - 將RIGHT JOIN有效轉換爲JOIN

將條款拉低到JOIN條件以使此工作成功。

我簡化了一些其他的事情。

+0

非常感謝您的回答,尤其是解釋!你的答案解決了這個問題。 – zehpunktbarron