Using MySQL, I’d like to list all users that don’t have the document “liaison”. It could means Users that does not have any document at all, or users that have documents, but not “liaison” in these ones.
How can I do using MySQL Query ? I can’t make it work!
Here’s the (simple) model
Users (id, name)
Documents (id, user_id, name, path)
The
NOT EXISTSis a workable solution. As an alternative, sometimes, with large sets, an “anti JOIN” operation can give better performance:The inline view aliased as
lreturns us a list of user_id that have document named ‘liaison’; that result set gets outer joined to the Users table, and then we exclude any rows where we found a match (the test of l.user_id IS NULL).This returns a resultset equivalent to your query with the
NOT EXISTSpredicate.Another alternative is to use a query with a
NOT INpredicate. Note that we need to guarantee that the subquery does not return a NULL, so the general approach is to include an IS NOT NULL predicate on the column being returned by the subquery.I’d write the
NOT EXISTSquery like this:My personal preference is to use a literal 1 in the SELECT list of that correlated subquery; it reminds me that the query is just looking for the existence of 1 row.)
Again, I usually find that the “anti-join” pattern gives the best performance with large sets. (You’d need to look at the EXPLAIN output for each statement, and measure the performance of each to determine which will work best in your situation.)