ホームページ > データベース > mysql チュートリアル > PostgreSQL の LEFT JOIN がカウント 0 の行を返さないのはなぜですか?

PostgreSQL の LEFT JOIN がカウント 0 の行を返さないのはなぜですか?

DDD
リリース: 2025-01-14 11:12:10
オリジナル
492 人が閲覧しました

Why Doesn't My PostgreSQL LEFT JOIN Return Rows with a Count of 0?

PostgreSQL の LEFT JOIN と欠落ゼロのカウント

PostgreSQL の LEFT JOIN は、右側のテーブルに一致する行がない場合でも、左側のテーブルからすべての行を返すように設計されています。 ただし、WHERE 句の条件が不適切に配置されていると、実質的に LEFT JOININNER JOIN に変わり、カウントがゼロの行が省略される可能性があります。

この問題は、適切なテーブルに基づくフィルタリング条件が WHERE 句に配置されている場合によく発生します。 次の例を考えてみましょう:

<code class="language-sql">SELECT o.name AS organisation_name,
       COALESCE(COUNT(exam_items.id)) AS total_used
FROM   organisations o
LEFT   JOIN exam_items e ON o.id = e.organisation_id
WHERE  e.item_template_id = #{sanitize(item_template_id)}
AND    e.used = true
GROUP  BY o.name
ORDER  BY o.name</code>
ログイン後にコピー

WHERE 句は、特定の exam_itemsitem_template_id に対して used = true をフィルターします。これにより、結合のがフィルタリングされ、これらの条件を満たす organisations 内に一致する行がない行を exam_items から削除します。

解決策: フィルタリングを JOIN 条件に再配置します

organisations に一致する行がない行も含め、exam_items のすべての行を保持するには、フィルター条件を WHERE 句から JOIN 句に移動します。

<code class="language-sql">SELECT o.name AS organisation_name,
       COUNT(e.id) AS total_used
FROM   organisations o
LEFT   JOIN exam_items e
       ON e.organisation_id = o.id
       AND e.item_template_id = #{sanitize(item_template_id)}
       AND e.used = true
GROUP  BY o.name
ORDER  BY o.name</code>
ログイン後にコピー

現在、フィルタリングは結合中に行われます。基準を満たす exam_items 行のみが結合の対象となります。 一致する行がない organisations 行も引き続き含まれるため、total_used の値は 0 になります。

さらなる最適化: COUNT() と COALESCE

元のクエリでは COALESCE(COUNT(exam_items.id)) が使用されています。これは冗長です。 COUNT()NULL を返しません。一致する行がない場合は 0 を返します。 したがって、COALESCE は不要であり、クエリ効率を向上させるために削除できます。

以上がPostgreSQL の LEFT JOIN がカウント 0 の行を返さないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート