 <p>Consider the following test case:</p> <pre><code>CREATE TABLE accounts (id int); CREATE TABLE emails (id int, account_id int, type_name varchar(10), order_id int); INSERT INTO accounts VALUES (1), (2), (3), (4); INSERT INTO emails VALUES (1, 1, 'name', 1); INSERT INTO emails VALUES (2, 1, 'no-name', 1); INSERT INTO emails VALUES (3, 2, 'name', 1); INSERT INTO emails VALUES (4, 2, 'no-name', 1); INSERT INTO emails VALUES (5, 3, 'name', 2); </code></pre> <p>Then this works as expected:</p> <pre><code>SELECT * FROM `accounts` LEFT OUTER JOIN `emails` ON emails.account_id = accounts.id WHERE (emails.type_name = 'name' AND emails.order_id = 1); +------+------+------------+-----------+----------+ | id | id | account_id | type_name | order_id | +------+------+------------+-----------+----------+ | 1 | 1 | 1 | name | 1 | | 2 | 3 | 2 | name | 1 | +------+------+------------+-----------+----------+ 2 rows in set (0.00 sec) </code></pre> <p>The problem with your second query is that it can return a <code>NULL</code> row if there is an account with no email, as is the case of account number 4: </p> <pre><code>SELECT * FROM `accounts` LEFT OUTER JOIN `emails` ON emails.account_id = accounts.id WHERE (!(emails.type_name = 'name' AND emails.order_id = 1) OR emails.id IS NULL); +------+------+------------+-----------+----------+ | id | id | account_id | type_name | order_id | +------+------+------------+-----------+----------+ | 1 | 2 | 1 | no-name | 1 | | 2 | 4 | 2 | no-name | 1 | | 3 | 5 | 3 | name | 2 | | 4 | NULL | NULL | NULL | NULL | +------+------+------------+-----------+----------+ 4 rows in set (0.01 sec) </code></pre> <p>Why wouldn't this be enough for a mutually exclusive result set with no <code>NULL</code> rows?:</p> <pre><code>SELECT * FROM `accounts` LEFT OUTER JOIN `emails` ON emails.account_id = accounts.id WHERE NOT (emails.type_name = 'name' AND emails.order_id = 1) +------+------+------------+-----------+----------+ | id | id | account_id | type_name | order_id | +------+------+------------+-----------+----------+ | 1 | 2 | 1 | no-name | 1 | | 2 | 4 | 2 | no-name | 1 | | 3 | 5 | 3 | name | 2 | +------+------+------------+-----------+----------+ 3 rows in set (0.00 sec) </code></pre>