Se a consulta envolver grandes partes de
b
e/ou c
é mais eficiente agregar primeiro e juntar depois.Espero que essas duas variantes sejam consideravelmente mais rápidas:
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);
Você precisa considerar a possibilidade de que algum
a_id
não estão presentes em a
e/ou b
. count()
nunca retorna NULL
, mas isso é um conforto frio diante de LEFT JOIN
, o que deixa você com NULL
valores para linhas ausentes, no entanto. Você deve prepare-se para NULL
. Use COALESCE()
. Ou UNION ALL
a_id
de ambas as tabelas, agregar, então JUNTE: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);
Provavelmente mais lento. Mas ainda mais rápido do que as soluções apresentadas até agora. E você poderia ficar sem
COALESCE()
e ainda não solta nenhuma linha. Você pode receber NULL
ocasional valores para bc_ct
, nesse caso.