【问题标题】:Is it possible to make this request with a join?是否可以通过加入提出此请求?
【发布时间】:2020-02-06 22:44:07
【问题描述】:

有 2 个表: - 用户(id,伪) - Link(id1,id2),这两列是 id User 上的 FK

我想选择所有没有链接的 id = 10 的用户。这意味着我想要用户的所有 id,但前提是 Link(10, id2) 不存在。

我尝试了左连接,但结果不正确

select distinct *
from USER
left join LINK on USER.id = LINK.id1
where LINK.id1 != 10

【问题讨论】:

  • 了解 LEFT JOIN ON 返回的内容:INNER JOIN ON 行 UNION ALL 不匹配的左表行,由 NULL 扩展。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。 WHERE 或 INNER JOIN ON 在 OUTER JOIN ON 删除任何由 NULL 扩展的行后,需要右 [sic] 表列不为 NULL,即只留下 INNER JOIN ON 行,即“将 OUTER JOIN 转换为 INNER JOIN”。你有那个。这是一个很容易找到的常见问题解答。

标签: sql performance join


【解决方案1】:

这里的一个存在查询似乎是最直接的:

SELECT u.id, u.pseudo
FROM User u
WHERE NOT EXISTS (SELECT 1 FROM Link l
                  WHERE (l.id1 = u.id AND l.id2 = 10) OR (l.id2 = u.id AND l.id1 = 10));

在简单的英语中,这表示保留User 表中的每条记录,这样该用户和id = 10 之间不存在任何关系。请注意,我在Link 表中检查关系的双方,假设我们不知道任何用户可能会落在哪一边。

【讨论】:

  • 谢谢它太完美了,你认为我有很多记录会出现性能问题吗?
  • 您可以尝试将索引(id1, id2) 添加到Link 表中,这可能让您的数据库更快地评估NOT EXISTS 子句。我们可能会调整我的答案,以便您在性能方面可以接受。
【解决方案2】:

ON 子句中添加条件LINK.id1 = 10,在WHERE 子句中只返回不匹配的行:

select distinct USER.* 
from USER left join LINK 
on USER.id = LINK.id1 and LINK.id1 = 10
where LINK.id1 is null

不清楚您是否只希望id1 不等于 10 或 id2

【讨论】:

    猜你喜欢
    • 2012-07-17
    • 2015-02-14
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    相关资源
    最近更新 更多