Pokud dotaz zahrnuje velké části b
a / nebo c
je efektivnější nejprve agregovat a připojit se později.
Očekávám, že tyto dvě varianty budou podstatně rychlejší:
SELECT a.id,
,COALESCE(b.ct, 0) + COALESCE(c.ct, 0) AS bc_ct
FROM a
LEFT JOIN (SELECT a_id, count(*) AS ct FROM b GROUP BY 1) b USING (a_id)
LEFT JOIN (SELECT a_id, count(*) AS ct FROM c GROUP BY 1) c USING (a_id);
Musíte počítat s možností, že nějaké a_id
se v a
vůbec nevyskytují a / nebo b
. count()
nikdy nevrací NULL
, ale to je chladné pohodlí tváří v tvář LEFT JOIN
, což vám ponechá NULL
hodnoty pro chybějící řádky přesto. Musíte připravte se na NULL
. Použijte COALESCE()
.
Nebo UNION ALL a_id
z obou tabulek, agregovat, pak PŘIPOJTE SE:
SELECT a.id
,COALESCE(ct.bc_ct, 0) AS bc_ct
FROM a
LEFT JOIN (
SELECT a_id, count(*) AS bc_ct
FROM (
SELECT a_id FROM b
UNION ALL
SELECT a_id FROM c
) bc
GROUP BY 1
) ct USING (a_id);
Asi pomaleji. Ale stále rychlejší než dosud prezentovaná řešení. A můžete se obejít bez COALESCE()
a stále neztrácejí žádné řádky. Občas se může objevit NULL
hodnoty pro bc_ct
, v tomto případě.