Reputation: 20049
I have a situation where we have a table that contains all the items, if the item was sold it has an entry in another table.
I am trying to get all the items returned that have not been sold, but it doesn't seem to work.
I have this SQL:
SELECT a.auction_id FROM auctions AS a
LEFT JOIN winners AS w ON a.auction_id=w.auction_id AND w.winner_id IS NULL
WHERE a.owner_id=1234567 AND a.is_draft=0 AND a.creation_in_progress=0;
I thought this would only return items from the auctions
table that don't have a matched entry in the winners
table since I am doing AND w.winner_id IS NULL
.
However it seems to still return the same amount of rows as it does when I leave off AND w.winner_id IS NULL
.
Upvotes: 0
Views: 71
Reputation: 13248
SELECT a.auction_id
FROM auctions AS a
LEFT JOIN winners AS w
ON a.auction_id = w.auction_id
WHERE a.owner_id = 1234567
AND a.is_draft = 0
AND a.creation_in_progress = 0
AND w.winner_id IS NULL
This belongs in the WHERE clause:
AND w.winner_id IS NULL
Criteria on the outer joined table belongs in the ON clause when you want to ALLOW nulls. In this case, where you're filtering in on nulls, you put that criteria into the WHERE clause. Everything in the ON clause is designed to allow nulls.
Here are some examples using data from a question I answered not long ago:
Proper use of where x is null: http://sqlfiddle.com/#!2/8936b5/2/0
Same thing but improperly placing that criteria into the ON clause: http://sqlfiddle.com/#!2/8936b5/3/0
(notice the FUNCTIONAL difference, the result is not the same, because the queries are not functionally equivalent)
Upvotes: 3