3

我有这个 MySQL 查询:

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).

4

6 回答 6

3

根据要求,我的评论作为答案。

我的大脑说“区分大小写”,我的手指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() 添加到该字符串比较中。

于 2013-03-21T08:46:25.913 回答
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;
于 2013-03-20T14:05:35.177 回答
1

尝试使用NOT EXISTS而不是 NOT IN

像那样:

select e.* 
from emails as e 
where e.error <> 1 
AND e.login NOT EXISTS (select email_login from accounts ) 
于 2013-03-20T14:07:06.637 回答
0

我猜 e.login 或 email_login 有一个CHAR类型而不是VARCHAR. 因此,该字段用空格填充。

于 2013-03-20T14:11:20.617 回答
0

这可能是因为 e.login 为 NULL,当比较 NULL 值(如您的情况为 NOT IN)时,它总是返回 false(请参阅文档:运算符 NOT LIKE也适用于 NOT IN)。

您可以使用COALESCE()来检查这一点:

返回列表中的第一个非 NULL 值,如果没有非 NULL 值,则返回 NULL。

所以在你的情况下:

 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)))
于 2013-03-20T14:15:28.407 回答
0
SELECT * 
FROM emails e 
WHERE e.error <> 1
AND NOT EXISTS (
 SELECT * FROM accounts a
 WHERE a.email_login = e.login
 )
;
于 2013-03-20T14:48:51.440 回答