使用 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中文網其他相關文章!