sql从表中选择未出现在第二个表中的所有内容

时间:2016-12-16 04:19:20

标签: mysql sql join mysqli subquery

我有三张桌子 -

Users [Id,Name]
Matches_A [Id1,Id2]
Matches_B[Id1,Id2]

我知道当前用户的user_id。

对于每个Id1,在任一匹配表中,都有许多条目。也就是说,两个表中的每个用户都有许多匹配项。

我需要选择不在任何匹配表中的所有用户。

我尝试了这个查询 -

SELECT * FROM Users 
JOIN Matches_A ON Users.id = Matches_A.id2 
JOIN Matches_B on Users.id = Matches_B.id2
WHERE Matches_A.id1 != $userid
AND Matches_B.id1 != $userid;

这不起作用。

问题是Matches表中的条目具有相同的id2但不同的id1。这意味着即使我排除了id1与userid匹配的行,仍然可以返回该用户(id2),因为存在另一行,其中id1与user_id不匹配。

如果这没有意义,那就让我改一下吧。选择我不想退回的所有内容都很容易。

SELECT * FROM Users 
JOIN Matches_A ON Users.id = Matches_A.id2 
JOIN Matches_B on Users.id = Matches_B.id2
WHERE Matches_A.id1 != $userid
AND Matches_B.id1 = $userid;

会返回我不想要的所有行。如何编写一个查询来获取所有其他行。

P.S。使用子查询很容易做到这一点,但我担心这会很慢,特别是对于3个表。

4 个答案:

答案 0 :(得分:0)

考虑not innot exists而不是join

SELECT *
FROM Users u
WHERE u.id NOT IN (SELECT a.id2 FROM Matches_A) AND 
      u.id NOT IN (SELECT b.id2 FROM Matches_B);

此版本假定任一表中id2永远不会NULL

答案 1 :(得分:0)

尝试附加图像的解决方案。你会明白使用左连接和使用null。 让我知道这有帮助。 https://i.stack.imgur.com/YR5aK.png

答案 2 :(得分:0)

您可以尝试使用 NOT EXISTS

SELECT u.*
FROM Users u
WHERE NOT EXISTS (SELECT a.id2 FROM Matches_A a WHERE a.id2 = u.id 
                  UNION ALL 
                  SELECT b.id2 FROM Matches_B b WHERE b.id2 = u.id)

答案 3 :(得分:0)

最简单的解决方案是使用EXCEPT

WITH Subset as (SELECT id from users EXCEPT
                (SELECT id2 from Matches_A 
                 UNION
                 SELECT id2 from Matches_B))
SELECT * FROM Users NATURAL JOIN Subset;