简体   繁体   中英

Difference between these two queries

Below are two queries (WHERE query and JOIN query). The two queries have the potential to return two different result sets.

Which query might return more rows?
What subset of data must exist in order to have the queries return a different number of rows?

WHERE query:

SELECT COUNT(u.uid), r.name
FROM role r
LEFT JOIN users_roles ur ON r.rid = ur.rid
LEFT JOIN users u ON ur.uid = u.uid
WHERE u.status <> 0
GROUP BY r.rid

JOIN query:

SELECT COUNT(u.uid), r.name
FROM role r
LEFT JOIN users_roles ur ON r.rid = ur.rid
LEFT JOIN users u ON ur.uid = u.uid AND u.status <> 0
GROUP BY r.rid

what is the main reason for returning diff results and whats the difference between these two queries?

The logic for a left outer join is the following. Compare all rows in the first table to all rows in the second table. If any pairs match the on condition, then keep them. If no rows match a particular row in the first table, then keep the row in the first table and make all the other columns NULL .

This logic applies in all cases. So, if you do:

select a.*
from a left join
     b
     on 1 = 0;

Then it will keep all rows in a , even though the on clause always evaluates to false. The filter has no effect, in a sense.

The same thing is happening in your query. When you have

ON ur.uid = u.uid AND u.status <> 0

It is saying to keep all the rows in the preceding tables. If there is a match with a non-zero status, then use that value for u.status . Otherwise, the value is NULL .

When you have instead:

WHERE u.status <> 0

Then you are really saying: the left join doesn't succeed and status <> 0. The "safer" way to write this is:

WHERE u.status <> 0 or u.status IS NULL

However, it is clearer to put the condition in the on clause, because it really is part of the left outer join .

The WHERE query checks for u.status <> 0 AFTER the join.
The JOIN query checks for u.status <> 0 as part of the join.

So WHERE query will not return anything if u.status = 0 whereas the JOIN query will, but will set all the fields from users to NULL.

By the way, COUNT(u.uid) is going to count the total number of non-null uid s are returned, not how many distinct uid s there are.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM