sql >> Database >  >> RDS >> PostgreSQL

Postgres - hoe rijen met 0-tellingen te retourneren voor ontbrekende gegevens?

Goede oplossing

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;
  • Gebruik LEFT JOIN , natuurlijk.

  • generate_series() kan on-the-fly en zeer snel een tabel met tijdstempels produceren.

  • Het is over het algemeen sneller om vóór . te verzamelen jij doet mee. Ik heb onlangs een testcase gegeven op sqlfiddle.com in dit gerelateerde antwoord:

    • PostgreSQL - rangschikken op array
  • Cast de timestamp tot date (::date ) voor een basisformaat. Gebruik voor meer to_char() .

  • GROUP BY 1 is een syntaxisafkorting om te verwijzen naar de eerste uitvoerkolom. Kan GROUP BY day zijn ook, maar dat kan in strijd zijn met een bestaande kolom met dezelfde naam. Of GROUP BY date_trunc('month', date_col)::date maar dat is te lang naar mijn smaak.

  • Werkt met de beschikbare intervalargumenten voor date_trunc() .

  • count() produceert nooit NULL (0 voor geen rijen), maar de LEFT JOIN doet.
    Te retourneren 0 in plaats van NULL in de buitenste SELECT , gebruik COALESCE(some_count, 0) AS some_count . De handleiding.

  • Voor een meer algemene oplossing of willekeurige tijdsintervallen overweeg dit nauw verwante antwoord:

    • De beste manier om records te tellen met willekeurige tijdsintervallen in Rails+Postgres


  1. Sequentiële doorvoersnelheden en feeds

  2. Een string invoegen in een andere string in MySQL met INSERT()

  3. Snel script dat alle eigenschappen van SERVERPROPERTY() retourneert in SQL Server 2017/2019

  4. Kan argument niet binden aan index 2 omdat de index buiten bereik is