【问题标题】:sql select everything from the table that does not appear in a second tablesql 从表中选择未出现在第二个表中的所有内容
【发布时间】: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 个表。

【问题讨论】:

    标签: mysql sql join subquery


    【解决方案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 更快。如果我们没有大量数据,那么您可以使用任何数据。
    • 您的查询必须为用户中的每个元组执行一个子查询。子查询返回多少结果并不重要。问题是它必须执行它。
    • 请查看stackoverflow.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

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 2019-05-04
      • 2021-03-12
      • 2010-12-21
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多