Wenn die Abfrage große Teile von b
enthält und / oder c
es ist effizienter, zuerst zu aggregieren und später zusammenzufügen.
Ich erwarte, dass diese beiden Varianten erheblich schneller sind:
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);
Sie müssen die Möglichkeit berücksichtigen, dass einige a_id
sind in a
überhaupt nicht vorhanden und / oder b
. count()
gibt niemals NULL
zurück , aber das ist angesichts von LEFT JOIN
ein schwacher Trost , was Sie mit NULL
zurücklässt dennoch Werte für fehlende Zeilen. Sie müssen auf NULL
vorbereiten . Verwenden Sie COALESCE()
.
Oder UNION ALL a_id
aus beiden Tabellen, aggregiert, dann VERBINDEN:
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);
Wahrscheinlich langsamer. Aber immer noch schneller als bisher vorgestellte Lösungen. Und Sie könnten auf COALESCE()
verzichten und immer noch keine Reihen verlieren. Sie erhalten möglicherweise gelegentlich NULL
Werte für bc_ct
, in diesem Fall.