首頁 >資料庫 >mysql教程 >為什麼我的 LEFT JOIN 在 PostgreSQL 中傳回不正確的計數?

為什麼我的 LEFT JOIN 在 PostgreSQL 中傳回不正確的計數?

DDD
DDD原創
2025-01-14 11:17:43125瀏覽

Why Does My LEFT JOIN Return Incorrect Counts in PostgreSQL?

PostgreSQL LEFT JOIN:解不正確的計數結果

在 PostgreSQL 中使用 LEFT JOIN 對每個組織的條目進行計數時,您可能會遇到僅傳回計數大於零的組織的情況。 這與 LEFT JOIN 的預期行為相矛盾,LEFT JOIN 應包括所有組織,無論它們在連接表中是否有匹配的條目。

更正 LEFT 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>

關鍵的修改涉及將 e.used 條件從 WHERE 子句(它充當 連接之後的過濾器)移動到 ON 子句(其中它充當連接條件) )。這可確保只有滿足所有條件的符合行才會包含在連線本身中,從而防止意外過濾計數為零的組織。

最佳化方法:預先聚合

為了提高效能,特別是在處理大型資料集時,請考慮以下替代查詢:

<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
    GROUP BY
      1
  ) AS e
  USING (id)
ORDER BY
  o.name,
  o.id;</code>

此方法首先聚合子查詢中的計數,然後執行連線。 這種預聚合可以顯著提高效率,特別是當計數中包含大部分 exam_items 行時。 COALESCE 函數處理 total_used 為 NULL 的情況(對於沒有匹配條目的組織),將其替換為 0 以保持一致性。

以上是為什麼我的 LEFT JOIN 在 PostgreSQL 中傳回不正確的計數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn