Hvis forespørgslen involverer store dele af b
og/eller c
det er mere effektivt at samle først og slutte sig til senere.
Jeg forventer, at disse to varianter er betydeligt hurtigere:
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);
Du skal tage højde for muligheden for, at nogle a_id
er slet ikke til stede i a
og/eller b
. count()
returnerer aldrig NULL
, men det er kold komfort over for LEFT JOIN
, hvilket efterlader dig med NULL
værdier for manglende rækker alligevel. Du skal forberede dig på NULL
. Brug COALESCE()
.
Eller UNION ALL a_id
fra begge tabeller, samle, derefter JOIN:
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);
Formentlig langsommere. Men stadig hurtigere end de hidtil præsenterede løsninger. Og du kunne undvære COALESCE()
og stadig ikke miste nogen rækker. Du får muligvis lejlighedsvis NULL
værdier for bc_ct
, i dette tilfælde.