sql >> Database >  >> RDS >> PostgreSQL

Doe mee aan een telquery op generation_series() en haal null-waarden op als '0'

Ontward, vereenvoudigd en gefixeerd, het zou er zo uit kunnen zien:

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;

db<>viool hier

Tussen al het lawaai, de misleidende identificatiecodes en het onconventionele formaat was het eigenlijke probleem hier verborgen:

WHERE version = 1

Je hebt correct gebruik gemaakt van RIGHT [OUTER] JOIN . Maar het toevoegen van een WHERE clausule die een bestaande rij vereist uit mytable converteert de RIGHT [OUTER] JOIN naar een [INNER] JOIN effectief.

Verplaats dat filter naar de JOIN voorwaarde om het te laten werken.

Ik heb wat andere dingen vereenvoudigd terwijl ik bezig was.

Beter, maar toch

SELECT to_char(mon, 'yyyy-mm') AS monat
     , COALESCE(t.ct, 0) AS eintraege
FROM  (
   SELECT date_trunc('month', date_from)::date AS mon
        , count(*) AS ct
   FROM   mytable
   WHERE  version = 1     
   GROUP  BY 1
   ) t
RIGHT JOIN (
   SELECT generate_series(date_trunc('month', min(date_from))
                        , max(date_from)
                        , interval '1 mon')::date
   FROM   mytable
   ) m(mon) USING (mon)
ORDER  BY mon;

db<>viool hier

Het is veel goedkoper om eerst te verzamelen en later mee te doen - één rij per maand in plaats van één rij per dag.

Het is goedkoper om GROUP BY te baseren en ORDER BY op de date waarde in plaats van de weergegeven text .

count(*) is een beetje sneller dan count(id) , terwijl het equivalent is in dit vraag.

generate_series() is een beetje sneller en veiliger wanneer gebaseerd op timestamp in plaats van date . Zie:

  • Tijdreeksen genereren tussen twee datums in PostgreSQL



  1. Hoe de ORA-00936 ontbrekende uitdrukking op te lossen?

  2. Primaire SQL-sleutel

  3. De laatste N rijen in de database op volgorde krijgen?

  4. Hoe een weergave te maken in Oracle