sql 从表中选择未出现在第二个表中的所有内容
Posted
技术标签:
【中文标题】sql 从表中选择未出现在第二个表中的所有内容【英文标题】:sql select everything from the table that does not appear in a second table 【发布时间】:2017-05-01 19:50:25 【问题描述】:我有三张桌子 -
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;
将返回所有我不想要的行。我如何编写一个查询来获取所有其他行。
附:使用子查询很容易做到这一点,但我担心这会很慢,尤其是 3 个表。
【问题讨论】:
【参考方案1】:最简单的解决方案是使用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;
【讨论】:
你认为 EXCEPT 在 mysql 中有效吗?尝试正确阅读问题并查看 TAG,然后仅尝试回答任何问题。 我猜不是。那就是mysql用户的流失。 :)【参考方案2】:您也可以尝试 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)
【讨论】:
如果用户有很多元组,这个查询会非常慢。 这取决于子查询返回的行数,如果子查询结果很大,则 NOT EXISTS 执行得更快,如果子查询结果很小,则 NOT IN 更快。如果我们没有大量数据,那么您可以使用任何数据。 您的查询必须为用户中的每个元组执行一个子查询。子查询返回多少结果并不重要。问题是它必须执行它。 请查看***.com/questions/14190788/… 并尝试限制 cmets。如果您也不相信这一点,那么请以您的方式完成您的工作,但不要以这种方式建议其他人。谢谢【参考方案3】:想想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
。
【讨论】:
以上是关于sql 从表中选择未出现在第二个表中的所有内容的主要内容,如果未能解决你的问题,请参考以下文章
更好的方法来选择第一个表中的所有列,并且只选择第二个表中的一列。
我有两个带外键的表,我想在第一个表中按下外键,第二个表出现数据
Django Admin,我的表的所有内容都没有显示和内联问题