Ако заявката включва големи части от b и / или c по-ефективно е първо да се агрегира и да се присъедини по-късно.
Очаквам тези два варианта да бъдат значително по-бързи:
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);
Трябва да отчетете възможността някои a_id изобщо не присъстват в a и / или b . count() никога не връща NULL , но това е студена утеха в лицето на LEFT JOIN , което ви оставя с NULL въпреки това стойности за липсващи редове. Вие трябва подготви се за NULL . Използвайте COALESCE()
.
Или UNION ALL a_id от двете таблици, обобщете, след това ПРИСЪЕДИНЕТЕ СЕ:
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);
Вероятно по-бавно. Но все пак по-бързо от представените досега решения. И можете да направите без COALESCE() и все още не губи нито един ред. Понякога може да получите NULL стойности за bc_ct , в този случай.