3

I have this MySQL query:

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

But it returns 0 rows.

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

Does work correctly.

email_login is varchar(255) and id is int(11).

12
  • You absolutely sure? what if you rewrite statement using not exists ? Commented Mar 20, 2013 at 14:01
  • You should take a look at the LEFT JOIN operator Commented Mar 20, 2013 at 14:01
  • A fiddle at sqlfiddle.com would also help a lot Commented Mar 20, 2013 at 14:01
  • 5
    well, maybe case-sensitivity leads to your problem, try ...UPPER(e.login) NOT IN ( SELECT UPPER(email_login) FROM accounts WHERE email_login IS NOT NULL ) Commented Mar 20, 2013 at 14:02
  • 1
    @Najzero: Thank you very much WHERE email_login IS NOT NULL is the solution :) Commented Mar 20, 2013 at 14:07

6 Answers 6

3

As requested, my comment as an answer.

My brain said "case sensitive", my fingers added IS NOT NULL to the subquery automaticly. My smart fingers bypass NOT NULL problems in comparism :-).

Here is your working query:

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) 

my fingers added the UPPER() to that string comparism this time too.

Sign up to request clarification or add additional context in comments.

1 Comment

UPPERCASE is not necessary. In my case there is no option to be different data :) (email logins).
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;

6 Comments

Thank you but the solution is WHERE email_login IS NOT NULL I don't want to use joins
Is that a moral or an emotional objection?
I am not sure but I think joins are very slow.
Ah, I see - a religious objection - based upon your beliefs. Well, fair enough ;-)
I heard while loops are slow too. After all they run the same block of code again and again! What's up with that? I'm not going to use loops anymore. ;-)
|
1

Try with NOT EXISTS instead of NOT IN

like that:

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

Comments

0

I guess either e.login or email_login has a CHAR type instead of VARCHAR. Hence that field is padded with blanks.

Comments

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

Comments

0

This could be because e.login is NULL, when comparing NULL valuse as in your case as NOT IN it allways returns false (See documentation: operator NOT LIKE which applies to NOT IN too).

You can check this by using COALESCE() which:

Returns the first non-NULL value in the list, or NULL if there are no non-NULL values.

So in your case:

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

If this does not work try depending on how exact should be compared either the LIKE operator or the trimmed values to avoid differences because of leading or trailing spaces

With %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 ,'%'))

Notice that the % matches any number of characters, including zero characters

To match the exact 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)))

3 Comments

-1 You can't put identifiers inside a string literal like that. Why give an answer of "try this" when you obviously haven't tried it?
@BillKarwin thank you, fixed. And by the way it is ok to provide an idea answer even if the i did not try it.
Ok, I reversed my downvote since you have corrected the answer. I don't agree that it's okay to post answers that are pure guesses, and grossly wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.