简体   繁体   中英

SQL NOT query returns wrong results

I have 2 SQL tables. users contains users and registrants contains all the registrations done for an event. Given that I have the id of the event - I am successfully printing out those users that are registered for a specific event. However I want to print all the users that are NOT registered for the event and here I fail at producing the correct result. My query is as follows:

SELECT users.fName, users.lName, users.uid
FROM users, registrants
WHERE registrants.tourId = '$id' AND NOT registrants.pId = users.uid

The result of this is an array of 33 users printed out, although I have only 12, 3 of which are already registered for the event. Is the SELECT command wrong or I will need to dig into the php code, although I am pretty sure all the work there is correct.

By specifying no JOIN syntax, but instead specifying a kind of inequality join in the WHERE clause, you are effectively asking SQL to find all combinations of users and registrants, with the additional filter criteria in the WHERE clause, hence the large number of rows.

I believe the query you are looking for is more like this:

SELECT users.fName, users.lName, users.uid
FROM users
WHERE users.uid NOT IN (
   SELECT registrants.pId 
   FROM registrants
   WHERE registrants.tourId = '$id');

"Find all users, except those registered for tourId = '$id'"

Assuming that "registrants.pId" is the foreign key to the table "users", this request will give you every combination of registrants and users where the registrant and user are not related.

The way I see you could achieve the intended result is to select users using a subquery to exclude those who are regitered to the event. Which would look something like :

$query = "SELECT users.fName, users.lName, users.uid FROM users WHERE users.uid not in (SELECT users.uid FROM users, registrants WHERE registrants.tourId = '$id' AND registrants.pId = users.uid)"

there might be a simpler way to do this, though I do not see it right now.

Have you tried ".... AND registrants.pld <> users.uid"; ?

or

".... AND registrants.pld != users.uid";

You need to use an anti-join, that is, an outer join where you want to return from the dependent side of the join values where the independent side of the join is null.

In your case that looks like this:

SELECT users.fName, users.lName, users.uid
FROM users
LEFT OUTER JOIN registrants
ON users.uid = registrants.pId
AND registrants.tourId = '$id'
WHERE registrants.pId IS NULL

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