Reputation: 531
I created a relatively simple query in MySQL to give me a JOIN
on three tables based on where first names and last names matched. From there, I wanted to write another query that would then only show me the records that didn't get matched from the JOIN
-- but I couldn't quite figure out how to do it. I'm assuming that it has to do with using a subquery involving something like NOT IN
and my original query, but I couldn't get it to give me the results I wanted.
This is the work-around I tried to come up with that partially functioned properly:
SELECT *,
if(t2.first=t1.first AND t2.last=t1.last, "Match", "No Match") AS "t2 Match",
if(t3.first=t1.first AND t3.last=t1.last, "Match", "No Match") AS "t3 Match"
FROM t1
LEFT JOIN t2 ON t2.first=t1.first AND t2.last=t1.last
LEFT JOIN t3 ON t3.first=t1.first AND t3.last=t1.last
WHERE if(t2.first=t1.first AND t2.last=t1.last, "Match", "No Match")="No Match"
OR if(t3.first=t1.first AND t3.last=t1.last, "Match", "No Match")="No Match";
I feel like this is something that's fairly simple and straight-forward, but I'm not getting the correct results. Can anybody help?
Thanks!
Upvotes: 0
Views: 93
Reputation: 115630
No match means that the t2
(or t3
) columns are populated with Nulls in the results. So you can use IS NULL
checks:
SELECT t1.*
FROM t1
LEFT JOIN t2 ON t2.first = t1.first AND t2.last = t1.last
LEFT JOIN t3 ON t3.first = t1.first AND t3.last = t1.last
WHERE t2.first IS NULL
OR t3.first IS NULL ;
And you were right, you can also write the queries using NOT IN
(warning: only if the joining columns are not nullable. Otherwise you may have unexpected results):
SELECT t1.*
FROM t1
WHERE (first, last) NOT IN
( SELECT first, last FROM t2 )
OR (first, last) NOT IN
( SELECT first, last FROM t3 )
;
or using NOT EXISTS
:
SELECT t1.*
FROM t1
WHERE NOT EXISTS
( SELECT 1
FROM t2
WHERE t1.first = t2.first
AND t1.last = t2.last
)
OR NOT EXISTS
( SELECT 1
FROM t3
WHERE t1.first = t3.first
AND t1.last = t3.last
) ;
Upvotes: 5