Ако заявката включва големи части от 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
, в този случай.