sql >> Database teknologi >  >> RDS >> PostgreSQL

Postgres - hvordan returneres rækker med 0 antal for manglende data?

Korrekt løsning

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;
  • Brug LEFT JOIN selvfølgelig.

  • generate_series() kan producere en tabel med tidsstempler i farten, og meget hurtigt.

  • Det er generelt hurtigere at samle før du tilslutter dig. Jeg har for nylig leveret en testcase på sqlfiddle.com i dette relaterede svar:

    • PostgreSQL - bestil efter en matrix
  • Cast timestamp til date (::date ) for et grundlæggende format. For mere brug to_char() .

  • GROUP BY 1 er syntaksstenografi for at referere til den første outputkolonne. Kunne være GROUP BY day også, men det kan være i konflikt med en eksisterende kolonne af samme navn. Eller GROUP BY date_trunc('month', date_col)::date men det er for langt efter min smag.

  • Fungerer med de tilgængelige intervalargumenter for date_trunc() .

  • count() producerer aldrig NULL (0 for ingen rækker), men LEFT JOIN gør.
    For at returnere 0 i stedet for NULL i den ydre SELECT , brug COALESCE(some_count, 0) AS some_count . Manualen.

  • For en mere generisk løsning eller vilkårlige tidsintervaller overvej dette nært beslægtede svar:

    • Bedste måde at tælle poster efter vilkårlige tidsintervaller i Rails+Postgres


  1. SQLite Vælg

  2. Hvordan dropper man flere intervalpartitioner baseret på dato?

  3. fremad cross edition triggere i R12.2

  4. SQL Server-ydelse TOP IO-forespørgsel -2