Nếu truy vấn liên quan đến các phần lớn của b
và / hoặc c
sẽ hiệu quả hơn nếu tổng hợp trước và kết hợp sau.
Tôi hy vọng hai biến thể này sẽ nhanh hơn đáng kể:
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);
Bạn cần tính đến khả năng một số a_id
hoàn toàn không có trong a
và / hoặc b
. count()
không bao giờ trả về NULL
, nhưng đó là sự thoải mái lạnh lùng khi đối mặt với LEFT JOIN
, để lại cho bạn NULL
Tuy nhiên, giá trị cho các hàng bị thiếu. Bạn phải chuẩn bị cho NULL
. Sử dụng COALESCE()
.
Hoặc UNION ALL a_id
từ cả hai bảng, tổng hợp, sau đó THAM GIA:
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);
Có lẽ chậm hơn. Nhưng vẫn nhanh hơn các giải pháp được trình bày cho đến nay. Và bạn có thể làm mà không có COALESCE()
và vẫn không bị lỏng bất kỳ hàng nào. Bạn có thể nhận được NULL
không thường xuyên giá trị cho bc_ct
, trong trường hợp này.