开发者

What's the best way to use LEFT OUTER JOIN to check for non-existence of related rows

开发者 https://www.devze.com 2023-03-03 00:50 出处:网络
Using MySQL 5.x I want to efficiently select all rows from table X where开发者_StackOverflow there is no related row in table Y satisfying some condition, e.g.

Using MySQL 5.x I want to efficiently select all rows from table X where开发者_StackOverflow there is no related row in table Y satisfying some condition, e.g.

Give me all records in X where a related Y with foo = bar does NOT exist

SELECT count(id) FROM X
LEFT OUTER JOIN Y ON y.X_id = X.id AND y.foo = 'bar'
WHERE y....?

As I understand it, a left outer join is guaranteed to produce a row for each row in the left (first) table -- X in this case -- whether or not a satisfying row in the joined table was found. What I want to do is then select only those rows where no row was found.

It seems to me that y.X_id should be NULL if there is no matching record, but this test doesn't seem to work. Nor does y.X_id = 0 or !y.X_id.

Edits: corrected transcription error (ON not AS) which was pointed out by several responses. Fixed grammatical error.


SELECT count(id) FROM X 
LEFT OUTER JOIN Y ON (y.X_id = X.id AND y.foo = 'bar')
WHERE y.X_id is null

You were close.

First do the join as normal, then select all rows for which a not null row in Y is in fact null, so you are sure there's a "no match" and not just a null value in Y.

Also note the typo (since corrected) you made in the query:

LEFT OUTER JOIN Y AS
-- should be
LEFT OUTER JOIN Y ON
-- This however is allowed
LEFT OUTER JOIN table2 as Y ON ....


Checking if the primary key of table Y is NULL would do the trick, which tells the join did not matched :

SELECT count(id) FROM X 
LEFT OUTER JOIN Y ON (y.X_id = X.id AND y.foo = 'bar')
WHERE y.Y_id is null


Johan's answer is correct 100%.

Besides that, there is also this option:

SELECT count(id)
FROM X 
WHERE NOT EXISTS
  ( SELECT * 
    FROM Y
    WHERE (y.X_id = X.id AND y.foo = 'bar')
  )

Depending on your table size and data distribution, this may be more efficient. Test and keep both ways for future reference.


Why use an outer join? Couldn't you just do:

SELECT count(id) 
FROM X JOIN Y AS y.X_id = X.id AND y.foo <> 'bar'
0

精彩评论

暂无评论...
验证码 换一张
取 消