使用 LEFT JOIN 时的一个常见问题是无法为某些组返回零计数。 当过滤条件放在 WHERE 子句而不是 JOIN 子句中时,经常会发生这种情况。 此示例演示了如何正确构建 LEFT JOIN 以确保包含所有组织,即使是那些计数为零的组织。
问题是由于错误地放置了 WHERE 子句而产生的。 考虑这个更正后的查询:
<code class="language-sql">LEFT JOIN exam_items e ON e.organisation_id = o.id AND e.item_template_id = #{sanitize(item_template_id)} AND e.used</code>
将过滤条件(e.item_template_id
、e.used
)放置在 JOIN 子句中可确保仅连接匹配的行。 以前,将这些条件放在 WHERE 子句中无意中将 LEFT JOIN 转换为 INNER JOIN,排除了没有匹配条目的组织。
了解 COUNT(*)
和 COUNT(e.id)
始终返回数值(0 或更大)这一点至关重要,这与其他可能返回 NULL 的聚合函数不同。 因此,在这种情况下,不需要使用 COALESCE
来处理 NULL 值。
对于大多数 exam_items
行进行计数的场景,通过预聚合计数来实现性能增强:
<code class="language-sql">LEFT JOIN ( SELECT organisation_id AS id -- aliased for simpler join , COUNT(*) AS total_used -- COUNT(*) is generally faster FROM exam_items WHERE item_template_id = #{sanitize(item_template_id)} AND used GROUP BY 1 ) e USING (id)</code>
这种优化方法首先聚合来自 exam_items
的计数,然后与组织表执行更简单的联接。这可以显着提高查询速度,尤其是对于大型数据集。
以上是为什么我的 LEFT JOIN 不返回组织的零计数?的详细内容。更多信息请关注PHP中文网其他相关文章!