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;
Produceert het gewenste resultaat.
-
Herschrijven met expliciete
JOINsyntaxis. Maakt het zoveel gemakkelijker te lezen en te begrijpen (en debuggen). -
Door lid te worden van meerdere
1:ngerelateerde tabellen, zouden rijen elkaar vermenigvuldigen en een Cartesiaans product produceren - wat erg dure onzin is. Het is een onbedoeldeCROSS JOINbij volmacht. Gerelateerd: -
Om dit te voorkomen, moet u maximaal één deelnemen
n-tabel naar de1-tabel voordat u aggregeert (GROUP BY). Je zou twee keer kunnen aggregeren, maar het is schoner en sneller omnte aggregeren -tabellen afzonderlijk voor voeg ze toe aan de1-tafel. -
In tegenstelling tot uw originele (met impliciete
INNER JOIN). Ik gebruikLEFT JOINom te voorkomen dat u rijen verliest vanfoodie geen overeenkomende rij hebben infoo_baroftag. -
Zodra de onbedoelde
CROSS JOINis verwijderd uit de zoekopdracht, is het niet nodig omDISTINCTtoe te voegen meer - ervan uitgaande datfoo.idis uniek.