2013-03-20 85 views
2

我有這樣的MySQL查詢:MySQL的NOT IN不起作用

select e.* 
from emails as e 
where e.error <> 1 
AND e.login NOT IN (select email_login from accounts) 

但它返回0行。

select e.* 
from emails as e 
where e.error <> 1 
AND e.id NOT IN (select email_id from accounts) 

工作是否正常。

email_login是varchar(255),ID是int(11)

+0

你確定嗎?如果你用'not exists'重寫語句怎麼辦? – vittore 2013-03-20 14:01:40

+0

你應該看看'LEFT JOIN'運算符 – 2013-03-20 14:01:46

+0

http://sqlfiddle.com/上的小提琴也可以幫助很多 – 2013-03-20 14:01:59

回答

1

按照要求,作爲一個答案我的意見。

我的大腦說「區分大小寫」,我的手指自動將IS NOT NULL加到子查詢中。我的智能手指在比較中繞過NOT NULL問題:-)。

這是你的工作查詢:

SELECT e.* from emails AS e 
WHERE e.error <> 1 
AND UPPER(e.login) NOT IN 
(SELECTUPPER(email_login) FROM accounts WHERE email_login IS NOT NULL) 

我的手指加UPPER()到該字符串comparism這個時間太長。

+0

大寫是沒有必要的。在我的情況下,沒有選擇是不同的數據:)(電子郵件登錄)。 – mitch 2013-03-21 20:18:51

2
SELECT e.* 
    FROM emails e 
    LEFT 
    JOIN accounts a 
     ON a.email_login = e.login 
    WHERE e.error <> 1 
     AND a.email_login IS NULL; 
+0

謝謝,但解決方案是WHERE email_login不是NULL我不想使用連接 – mitch 2013-03-20 14:22:45

+1

這是道德還是感情上的異議? – Strawberry 2013-03-20 14:25:14

+0

我不確定,但我認爲連接非常緩慢。 – mitch 2013-03-20 14:27:35

1

NOT EXISTS,而不是不嘗試在

這樣的:

select e.* 
from emails as e 
where e.error <> 1 
AND e.login NOT EXISTS (select email_login from accounts) 
0

我想無論是e.login或email_login有CHAR類型,而不是VARCHAR。因此,該字段填充空白。

+0

不,這兩個都是varchar(255) – mitch 2013-03-20 14:53:54

0

這可能是因爲e.login爲NULL,因此在比較NULL值時與在您的情況下比較,因爲NOT IN它總是返回false(請參閱documentation: operator NOT LIKE,它也適用於NOT IN)。如果沒有 非NULL值

返回列表中的第一個非NULL值,或NULL:

您可以通過使用COALESCE()其檢查。

所以你的情況:

SELECT e.* 
FROM emails AS e 
WHERE e.error <> 1 
AND COALESCE(e.login,'') NOT IN (select email_login from accounts) 

如果這不起作用取決於嘗試如何確切應該比較無論是LIKE操作或修整值,以避免因爲開頭或結尾空格

的差異

憑藉%LIKE%

SELECT e.* 
FROM emails AS e 
WHERE e.error <> 1 
AND NOT EXISTS (SELECT email_login 
       FROM accounts 
       WHERE email_login LIKE CONCAT('%', e.login ,'%')) 

注意,%任意數量的字符,包括零個字符

匹配要匹配的確切登錄

SELECT e.* 
FROM emails AS e 
WHERE e.error <> 1 
AND NOT EXISTS (SELECT email_login 
       FROM accounts 
       WHERE UPPER(TRIM(email_login)) = UPPER(TRIM(e.login))) 
+1

-1您不能將標識符放入像這樣的字符串文字中。當你顯然沒有嘗試過時,爲什麼要給出「嘗試這個」的答案? – 2013-03-20 14:17:24

+0

@BillKarwin謝謝,修復。順便說一句,即使我沒有嘗試,也可以提供一個想法答案。 – CloudyMarble 2013-03-21 07:27:31

+1

好吧,我已經改正了答案,因此我反悔了。我不同意可以發佈純粹猜測的答案,而且是錯誤的。 – 2013-03-21 11:47:46

0
SELECT * 
FROM emails e 
WHERE e.error <> 1 
AND NOT EXISTS (
SELECT * FROM accounts a 
WHERE a.email_login = e.login 
) 
;