クエリにb
の大部分が含まれる場合 および/またはc
最初に集約して後で結合する方が効率的です。
これら2つのバリアントはかなり高速になると思います:
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);
a_id
の可能性を考慮する必要があります a
にはまったく存在しません および/またはb
。 count()
NULL
を返すことはありません 、しかしそれはLEFT JOIN
に直面したときの寒い快適さです 、NULL
が残ります それにもかかわらず、欠落している行の値。あなたはしなければならない NULL
の準備 。 COALESCE()
。
またはUNIONALLa_id
両方のテーブルから、集計し、次に 参加:
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);
おそらく遅い。しかし、これまでに提示されたソリューションよりもまだ高速です。そして、COALESCE()
なしで行うことができます それでも行を失うことはありません。ときどきNULL
が表示される場合があります bc_ct
の値 、この場合。