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

Samle funktioner på flere sammenføjede tabeller

SELECT f.id, f.name, b.fb_ct, t.tag_names
FROM   foo f
LEFT JOIN  (
    SELECT foo_id AS id, count(*) AS fb_ct
    FROM   foo_bar
    GROUP  BY 1
    ) b USING (id)
LEFT JOIN  (
    SELECT target_id AS id, array_agg(name) AS tag_names
    FROM   tag
    GROUP  BY 1
    ) t USING (id)
ORDER  BY f.id;

Giver det ønskede resultat.

  • Omskriv med eksplicit JOIN syntaks. Gør det så meget nemmere at læse og forstå (og fejlfinde).

  • Ved at slutte sig til flere 1:n relaterede tabeller, ville rækker multiplicere hinanden og producere et kartesisk produkt - hvilket er meget dyrt sludder. Det er en utilsigtet CROSS JOIN ved fuldmagt. Relateret:

  • For at undgå dette, tilmeld dig højst én n -tabellen til 1 -tabel, før du samler (GROUP BY ). Du kan samle to gange, men det er renere og hurtigere at samle n -tabeller separat før forbinder dem med 1 -bord.

  • I modsætning til din originale (med implicit INNER JOIN ). Jeg bruger LEFT JOIN for at undgå at miste rækker fra foo der ikke har nogen matchende række i foo_bar eller tag .

  • Når den utilsigtede CROSS JOIN er fjernet fra forespørgslen, er der ikke behov for at tilføje DISTINCT mere - forudsat at foo.id er unik.




  1. Rette:"Ukendt tabel 'locales' i informationsskema" i MariaDB

  2. Hvordan returnerer man en RefCursor fra Oracle-funktion?

  3. Sådan JSON analyserer billeder fra mysql og udfylder listevisning

  4. Definer en VIEW i Oracle uden at bruge CREATE