ロジックを単純化するには、最初に集約し、後で参加します。
不足している詳細を推測すると、このクエリは正確なカウント、各ユーザーがtable1
で参照された回数を提供します。 およびtable2
それぞれすべてのユーザー :
SELECT *
FROM users u
LEFT JOIN (
SELECT updated_by_id AS id, count(*) AS t1_ct
FROM table1
GROUP BY 1
) t1 USING (id)
LEFT JOIN (
SELECT updated_by_id AS id, count(*) AS t2_ct
FROM table2
GROUP BY 1
) t2 USING (id);
特に、複数の1-n関係が結合されたときに互いに乗算することは避けてください。
単一または少数のユーザーを取得するには のみ、LATERAL
結合が高速になります(Postgres 9.3以降):
SELECT *
FROM users u
LEFT JOIN LATERAL (
SELECT count(*) AS t1_ct
FROM table1
WHERE updated_by_id = u.id
) ON true
LEFT JOIN LATERAL (
SELECT count(*) AS t2_ct
FROM table2
WHERE updated_by_id = u.id
) ON true
WHERE u.id = 100;
知覚される違いを説明する
報告する特定の不一致は、FULL OUTER JOIN
:
したがって、一致が欠落している場合は、それぞれの反対側にNULL値が追加されます。 count()
NULL値はカウントされません。したがって、u1.id=100
でフィルタリングするかどうかによって、異なる結果を得ることができます。 またはu2.id=100
。
これは説明のためだけのもので、FULL JOIN
は必要ありません。 ここ。代わりに、提示された代替案を使用してください。