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
JOINsyntaks. Gør det så meget nemmere at læse og forstå (og fejlfinde). -
Ved at slutte sig til flere
1:nrelaterede tabeller, ville rækker multiplicere hinanden og producere et kartesisk produkt - hvilket er meget dyrt sludder. Det er en utilsigtetCROSS JOINved fuldmagt. Relateret: -
For at undgå dette, tilmeld dig højst én
n-tabellen til1-tabel, før du samler (GROUP BY). Du kan samle to gange, men det er renere og hurtigere at samlen-tabeller separat før forbinder dem med1-bord. -
I modsætning til din originale (med implicit
INNER JOIN). Jeg brugerLEFT JOINfor at undgå at miste rækker frafooder ikke har nogen matchende række ifoo_barellertag. -
Når den utilsigtede
CROSS JOINer fjernet fra forespørgslen, er der ikke behov for at tilføjeDISTINCTmere - forudsat atfoo.ider unik.