了解多個 SQL LEFT JOIN 的不準確存取計數
本文研究了一個常見的 SQL 查詢問題:使用多個 LEFT JOIN
操作時取得不正確的存取計數。 目標是檢索用戶數據,包括帳戶餘額、雜貨店訪問量和魚市場訪問量。 簡單的查詢通常會產生誇大的結果(例如“1”、“12”、“12”)。
問題源自於LEFT JOIN
從左到右的執行。 如果連接的表中有多個符合條目,則每個後續連接都會增加行數。 例如,將三個雜貨表連接到一個使用者會產生三行。 隨後與四個魚市場表的連接將其擴展到十二行,導致訪問計數不準確。
解決方案:使用子查詢進行預先聚合
解決方案涉及在將每個表加入 users
表之前預先聚合每個表的存取計數。這可以防止行乘法問題。 修正後的查詢使用子查詢來實現此目的:
<code class="language-sql">SELECT u.id, u.account_balance, g.grocery_visits, f.fishmarket_visits FROM users u LEFT JOIN ( SELECT user_id, COUNT(*) AS grocery_visits FROM grocery GROUP BY user_id ) g ON g.user_id = u.id LEFT JOIN ( SELECT user_id, COUNT(*) AS fishmarket_visits FROM fishmarket GROUP BY user_id ) f ON f.user_id = u.id ORDER BY u.id;</code>
使用 COALESCE 處理缺失值
為了優雅地處理使用者沒有存取特定位置的情況,COALESCE
函數可以將 NULL
值替換為 0(或任何其他所需值):
<code class="language-sql">SELECT u.id, u.account_balance, COALESCE(g.grocery_visits, 0) AS grocery_visits, COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits FROM users u LEFT JOIN ( SELECT user_id, COUNT(*) AS grocery_visits FROM grocery GROUP BY user_id ) g ON g.user_id = u.id LEFT JOIN ( SELECT user_id, COUNT(*) AS fishmarket_visits FROM fishmarket GROUP BY user_id ) f ON f.user_id = u.id ORDER BY u.id;</code>
這個改進的查詢準確地反映了每個使用者造訪雜貨店和魚市場的次數。 透過預先聚合數據,我們避免了級聯LEFT JOIN
的陷阱並確保準確的結果。
以上是為什麼多個 SQL LEFT JOIN 會產生不正確的存取計數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!