PostgreSQL LEFT JOIN 和缺失零計數
PostgreSQL 的 LEFT JOIN
旨在傳回左表中的所有行,即使右表中沒有符合項。 但是,放置不當的 WHERE
子句條件可以有效地將 LEFT JOIN
變成 INNER 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_items
和 item_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中文網其他相關文章!