簡體   English   中英

如何在MySQL中將NOT IN子句轉換為左外連接

[英]How can I convert a NOT IN Clause into a left outer join in MySQL

我試圖將查詢從NOT IS子句轉換為左外連接以獲得更好的性能。

以下是我的查詢完美

SELECT a.company_code, account_name, legal_name FROM accounts a

WHERE account_id NOT IN (SELECT DISTINCT  account_id FROM phone_calls WHERE status = 2 ) AND account_id >10000

ORDER BY legal_name, account_name, account_id

所以我想將它更改為左連接或某些類型的連接,它們將執行相同的查詢。 我試過這個,但它不適合我

SELECT a.company_code, a.account_name, a.legal_name, p.phone_call_id
FROM accounts AS a
LEFT JOIN phone_calls AS p ON p.account_id = a.account_id

WHERE a.account_id >= 10000 AND p.status = 2 AND p.phone_call_id IS NULL

ORDER BY a.legal_name, a.account_name, a.account_id

我的第二個查詢總是沒有返回。

我試過這個查詢,這給了我更多的結果,第一個查詢所以它不一樣

SELECT a.company_code, a.account_name, a.legal_name, p.phone_call_id
FROM accounts AS a
LEFT JOIN phone_calls AS p ON p.account_id = a.account_id AND p.status = 2 AND a.account_id >= 10000

WHERE p.account_id IS NULL

ORDER BY a.legal_name, a.account_name, a.account_id

join子句中檢查p.status = 2 ,而不是在where子句中:

SELECT a.company_code, a.account_name, a.legal_name, p.phone_call_id
FROM accounts AS a
LEFT JOIN phone_calls AS p ON p.account_id = a.account_id AND p.status = 2
WHERE a.account_id >= 10000  
AND p.phone_call_id IS NULL

ORDER BY a.legal_name, a.account_name, a.account_id

如果你將它放在where子句中,phone_calls將被加入,你將在加入后進行檢查

  • 那個p.status = 2
  • 那個p.phone_call_id是NULL

這些陳述可能完全沖突(所有帶狀態= 2的phone_calls都有一個id)。

一般來說,你不應該在WHERE子句中加入一個左連接子句( IS NULL / IS NOT NULL除外)

只是好奇,但嘗試使用NOT EXISTS子句:

SELECT company_code
     , account_name
     , legal_name 
FROM   accounts a
WHERE  account_id > 10000
   AND NOT EXISTS (
      SELECT 1 
      FROM phone_calls b
      WHERE b.status = 2 
        AND b.account_id = a.account_id
      )
ORDER BY legal_name, account_name, account_id

我認為只有一個EXPLAIN才能揭示哪種技術更好。 通過未選擇的列對結果進行排序似乎很奇怪,但這是一個不同的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM