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;
Produce il risultato desiderato.
-
Riscrivi con
JOINesplicito sintassi. Semplifica molto la lettura e la comprensione (e il debug). -
Unendo a più
1:ntabelle correlate, le righe si moltiplicherebbero a vicenda producendo un prodotto cartesiano - che è una sciocchezza molto costosa. È unCROSS JOINnon intenzionale per delega. Correlati: -
Per evitare ciò, unisciti al massimo a uno
n-tabella al1-table prima di aggregare (GROUP BY). Puoi aggregare due volte, ma è più semplice e veloce aggregaren-tabelle separatamente prima unendoli al1-tavolo. -
Al contrario del tuo originale (con
INNER JOINimplicito ). UsoLEFT JOINper evitare di perdere righe dafooche non hanno una riga corrispondente infoo_barotag. -
Dopo l'indesiderato
CROSS JOINviene rimosso dalla query, non è necessario aggiungereDISTINCTpiù - supponendo chefoo.idè unico.