Se la query coinvolge grandi parti di b e/o c è più efficiente aggregare prima e unire successivamente.
Mi aspetto che queste due varianti siano notevolmente più veloci:
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);
Devi tenere conto della possibilità che alcuni a_id non sono affatto presenti in a e/o b . count() non restituisce mai NULL , ma questo è un freddo conforto di fronte a LEFT JOIN , che ti lascia con NULL comunque i valori per le righe mancanti. devi prepararsi per NULL . Usa COALESCE()
.
Oppure UNION ALL a_id da entrambe le tabelle, aggrega, poi ISCRIVITI:
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);
Probabilmente più lento. Ma ancora più veloce delle soluzioni presentate finora. E potresti fare a meno di COALESCE() e ancora non perdere nessuna riga. Potresti ottenere occasionalmente NULL valori per bc_ct , in questo caso.