PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Postgres - Wie gibt man Zeilen mit 0 Zählern für fehlende Daten zurück?

Richtige Lösung

SELECT *
FROM  (
   SELECT day::date
   FROM   generate_series(timestamp '2007-12-01'
                        , timestamp '2008-12-01'
                        , interval  '1 month') day
   ) d
LEFT   JOIN (
   SELECT date_trunc('month', date_col)::date AS day
        , count(*) AS some_count
   FROM   tbl
   WHERE  date_col >= date '2007-12-01'
   AND    date_col <= date '2008-12-06'
-- AND    ... more conditions
   GROUP  BY 1
   ) t USING (day)
ORDER  BY day;
  • Verwenden Sie LEFT JOIN , natürlich.

  • generate_series() kann spontan und sehr schnell eine Tabelle mit Zeitstempeln erstellen.

  • Es ist im Allgemeinen schneller, vorher zu aggregieren du nimmst teil. Ich habe kürzlich einen Testfall auf sqlfiddle.com in dieser verwandten Antwort bereitgestellt:

    • PostgreSQL - Sortieren nach einem Array
  • Übertragen Sie den timestamp bis date (::date ) für ein Basisformat. Verwenden Sie für mehr to_char() .

  • GROUP BY 1 ist eine Syntax-Kurzform, um auf die erste Ausgabespalte zu verweisen. Könnte GROUP BY day sein auch, aber das könnte mit einer vorhandenen Spalte mit demselben Namen in Konflikt stehen. Oder GROUP BY date_trunc('month', date_col)::date aber das ist mir zu lang.

  • Funktioniert mit den verfügbaren Intervallargumenten für date_trunc() .

  • count() erzeugt niemals NULL (0 für keine Zeilen), sondern der LEFT JOIN tut.
    Um 0 zurückzugeben statt NULL im äußeren SELECT , verwenden Sie COALESCE(some_count, 0) AS some_count . Das Handbuch.

  • Für eine allgemeinere Lösung oder beliebige Zeitintervalle Betrachten Sie diese eng verwandte Antwort:

    • Der beste Weg, Datensätze in Rails+Postgres nach beliebigen Zeitintervallen zu zählen