Jeśli zapytanie obejmuje duże części b
i / lub c
bardziej wydajne jest agregowanie najpierw i dołączanie później.
Oczekuję, że te dwa warianty będą znacznie szybsze:
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);
Musisz wziąć pod uwagę możliwość, że niektóre a_id
w ogóle nie występują w a
i / lub b
. count()
nigdy nie zwraca NULL
, ale to zimny komfort w obliczu LEFT JOIN
, co oznacza NULL
mimo to wartości dla brakujących wierszy. musisz przygotuj się na NULL
. Użyj COALESCE()
.
Lub UNION ALL a_id
z obu tabel, agregacja, następnie DOŁĄCZ:
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);
Prawdopodobnie wolniej. Ale wciąż szybciej niż dotychczas prezentowane rozwiązania. I możesz obejść się bez COALESCE()
i nadal nie stracić żadnych rzędów. Czasami możesz otrzymać NULL
wartości dla bc_ct
, w tym przypadku.