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;
Vytváří požadovaný výsledek.
-
Přepište pomocí explicitního
JOINsyntax. Je to mnohem snazší číst a pochopit (a ladit). -
Připojením k více
1:nsouvisející tabulky, řádky by se navzájem násobily a vytvořily by kartézský produkt - což je velmi drahý nesmysl. Je to nechtěnéCROSS JOINpřes proxy. Související: -
Chcete-li se tomu vyhnout, připojte se nejvýše k jednému
n-tabulka na1-table před agregací (GROUP BY). Můžete agregovat dvakrát, ale je čistší a rychlejší agregovatn-tabulky samostatně před jejich připojením k1-stůl. -
Na rozdíl od vašeho originálu (s implicitním
INNER JOIN). PoužívámLEFT JOINaby nedošlo ke ztrátě řádků zfookteré nemají žádný odpovídající řádek vfoo_barnebotag. -
Jakmile dojde k nechtěnému
CROSS JOINje z dotazu odstraněn, není třeba přidávatDISTINCTnic víc - za předpokladu, žefoo.idje jedinečný.