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 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

【讨论】:

以上是关于sql 从表中选择未出现在第二个表中的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

更好的方法来选择第一个表中的所有列,并且只选择第二个表中的一列。

我有两个带外键的表,我想在第一个表中按下外键,第二个表出现数据

Django Admin,我的表的所有内容都没有显示和内联问题

如何只选择第二个表中的行?

从另一个表中选择一个表的否定以及oracle的主表sql查询中的数据

Excel:使用一个表中的值在第二个表中查找值