Jika kueri melibatkan sebagian besar b
dan / atau c
lebih efisien untuk menggabungkan terlebih dahulu dan bergabung kemudian.
Saya berharap kedua varian ini jauh lebih cepat:
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);
Anda perlu memperhitungkan kemungkinan bahwa beberapa a_id
tidak ada sama sekali di a
dan / atau b
. count()
tidak pernah mengembalikan NULL
, tapi itulah kenyamanan dingin dalam menghadapi LEFT JOIN
, yang meninggalkan Anda dengan NULL
nilai untuk baris yang hilang tetap. Anda harus bersiap untuk NULL
. Gunakan COALESCE()
.
Atau UNION SEMUA a_id
dari kedua tabel, agregat, lalu GABUNG:
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);
Mungkin lebih lambat. Tapi masih lebih cepat dari solusi yang disajikan sejauh ini. Dan Anda dapat melakukannya tanpa COALESCE()
dan masih tidak kehilangan baris. Anda mungkin sesekali mendapatkan NULL
nilai untuk bc_ct
, dalam hal ini.