Als de zoekopdracht grote delen van b
. omvat en / of c
het is efficiënter om eerst te aggregeren en later mee te doen.
Ik verwacht dat deze twee varianten aanzienlijk sneller zullen zijn:
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);
U moet rekening houden met de mogelijkheid dat sommige a_id
zijn helemaal niet aanwezig in a
en/of b
. count()
retourneert nooit NULL
, maar dat is koud comfort in het licht van LEFT JOIN
, waardoor je NULL
. krijgt waarden voor ontbrekende rijen toch. Je moet bereid je voor op NULL
. Gebruik COALESCE()
.
Of UNION ALL a_id
uit beide tabellen, aggregeren, vervolgens WORD LID:
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);
Waarschijnlijk langzamer. Maar nog steeds sneller dan de oplossingen die tot nu toe zijn gepresenteerd. En je zou kunnen doen zonder COALESCE()
en nog steeds geen rijen kwijt. Mogelijk krijg je af en toe NULL
waarden voor bc_ct
, in dit geval.