2012-11-16 3 views
7

Was ich erhalten möchte, ist eine Statistik mit jedem Monat von einer generate_series und die Summe der gezählten IDs in jedem Monat. Diese SQL arbeitet in PostgreSQL 9.1:Verknüpfen Sie eine Count-Abfrage auf einer generate_series in Postgres und auch Null-Werte als "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; 

Und das ist mein Ausgang

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

Aber was ich will bekommen ist dieser Ausgang (Wert "0" im Januar):

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

Also wenn es einen Monat ohne ID gibt sollte es trotzdem aufgelistet werden. Irgendwelche Ideen, um das zu lösen?

Hier einige Beispieldaten:

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; 

Unter all den Lärm, irreführende Identifikatoren und unkonventionelle Format das eigentliche Problem war:

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

Wie immer sollte die Tabellendefinition von 'mytable' in Ihrer Frage sein. Und einige Beispielwerte, um damit zu gehen, wären anschwellend. –

Antwort

16

Untangled, vereinfacht und fixiert, es könnte wie folgt aussehen Hier ausgeblendet:

WHERE version = 1 

Während Sie richtig verwendet RIGHT JOIN, haben Sie den Aufwand aufgegeben, indem Sie eine WHERE-Klausel hinzugefügt haben, die einen eindeutigen Wert von mytable erforderte - die RIGHT JOIN in eine JOIN effektiv umwandeln.

Ziehen Sie die Klausel in den Zustand JOIN, um dies zu erreichen.

Ich vereinfachte ein paar andere Dinge.

+0

Vielen Dank für Ihre Antwort und vor allem die Erklärung! Ihre Antwort löst das Problem. – zehpunktbarron

Verwandte Themen