首页 >数据库 >mysql教程 >为什么我的 LEFT JOIN 查询不返回计数为零的组织?

为什么我的 LEFT JOIN 查询不返回计数为零的组织?

Patricia Arquette
Patricia Arquette原创
2025-01-14 11:57:46269浏览

Why Doesn't My LEFT JOIN Query Return Organizations with a Count of Zero?

PostgreSQL LEFT JOIN:解决零计数组织问题

在 PostgreSQL 中使用 LEFT JOIN 时的一个常见挑战涉及检索关联记录的计数。 如果特定组织的计数为零,则该组织可能会从结果中省略。 本文解决了这个问题。

以下查询尝试对每个组织的已使用项目进行计数:

<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 子句。 WHERE 子句中放置的条件过滤 连接之后,当在 LEFT JOIN 中找不到匹配记录时,有效地将 INNER JOIN 转换为 exam_items

以下是改进版本:

解决方案 1:更正 JOIN 条件

WHERE 子句过滤掉计数为零的组织。 将 item_template_idused 条件移至 ONLEFT 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
GROUP BY o.name
ORDER BY o.name;</code>

此修订后的查询可确保包含所有组织,即使是 exam_items 中没有匹配条目的组织。

解决方案2:预聚合以提高效率

对于较大的数据集,预聚合exam_items可以显着提高性能:

<code class="language-sql">SELECT o.id, o.name AS organisation_name, COALESCE(e.total_used, 0) AS total_used
FROM organisations o
LEFT JOIN (
   SELECT organisation_id AS id, COUNT(*) AS total_used
   FROM exam_items
   WHERE item_template_id = #{sanitize(item_template_id)} AND used = TRUE
   GROUP BY 1
) e ON o.id = e.id
ORDER BY o.name, o.id;</code>

此方法首先聚合每个组织的计数,然后执行 LEFT JOIN,从而实现更高效的查询。 请注意使用 COALESCE 来处理 total_used 为 NULL 的情况。

通过实施这些解决方案中的任何一个,您将准确检索所有组织的已用项目数,包括那些计数为零的组织。 选择最适合您的数据大小和性能要求的解决方案。

以上是为什么我的 LEFT JOIN 查询不返回计数为零的组织?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn