我有三张桌子 -
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个表。
答案 0 :(得分:0)
考虑not in
或not 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;