【问题标题】:Can I join table one more time to existing join?我可以再一次加入表到现有的加入吗?
【发布时间】:2017-06-08 11:33:05
【问题描述】:

我有以下查询:

SELECT *
FROM A
  JOIN B ON A.id = B.a_id
  JOIN C ON B.id = C.b_id
  JOIN D ON C.id = D.c_id;

我需要将另一个表加入它 - 表 E。 但我需要在 B.id 和 E.a_id 上加入它。 我可以这样写查询吗:

SELECT *
FROM A
  JOIN B ON A.id = B.a_id
  JOIN C ON B.id = C.b_id
  JOIN D ON C.id = D.c_id
  JOIN E ON B.id = E.a_id;

这是正确的做法吗?

【问题讨论】:

  • 是的。 ON 子句可以引用FROM 子句中已经定义的任何表。
  • @GordonLinoff - 从技术上讲并不完全正确。您可以参考已经加入的表。仅当您对ON 子句的顺序感到困惑时,才会注意到这一点。例如。在select * from t1 inner join t2 inner join t3 on t1.id = t3.id on t2.id = t3.id 中,第一个on 子句出错,因为t1 不在范围内。

标签: sql database select join relational-database


【解决方案1】:

是的,你可以。如果您认为 join 只是将 tables 连接在一起,那么这可能是导致您出错的原因。

举个简单的例子:

SELECT *
FROM
   A
     INNER JOIN --J1
   B
     ON A.id = B.a_id
     INNER JOIN  --J2
   C
     ON B.id = C.b_id

如果我们查看第一个 JOINJ1,确实这是两个表之间的连接 - AB。但是在第二个JOINJ2 中,连接在表C前一个JOIN 的结果之间。此时,在此连接的 ON 子句中引用 ABC 中的任何一个都是有效的(或者都不引用,但这通常是一个错误)。

只要您不混用 ON 子句(每个 JOIN 后面紧跟其匹配的 ON 子句),每个 JOIN 总是会添加一个新表(或另一个实例现有表的) 到前一个JOIN 的结果上,所有表都将在ON 子句的范围内。


既然我已经在 cmets 中给出了它作为示例并且它证明了一个讨论点,那么让我们也有:

select
    *
from
    t1
       inner join --J1
    t2
       inner join --J2
    t3
       on t2.id = t3.id --O1
       on t1.id = t3.id --O2

这里发生了什么?好吧,JOINON 不必一起出现,它们实际上有点像括号。因此,在这个 from 子句中出现的第一个 JOINJ2 - 它与 O1 匹配。 JOIN 之后,我们使用O2 完成加入J1。在这种情况下,J1 最终是 t1t2t3 之间的连接结果

因为您必须仔细解析这种样式才能确定连接发生的顺序以及哪些ON 子句与哪个JOIN 匹配,所以我通常不建议编写这样的连接。

【讨论】:

  • 我不知道我们可以这样写:select * from t1 inner join t2 inner join t3 on t1.id = t3.id on t2.id = t3.id 在什么情况下我们需要将所有ON 子句放在所有JOIN 子句之后?
  • @Don_Quijote - 这只是一个变体。我通常不建议编写这样的查询,因为它很难阅读和理解。这只是说明为什么说ON 子句总是可以引用前面的表是不正确的。所以,简而言之,除非你想证明一个观点,否则不要这样写你的连接:-)
【解决方案2】:

是的,你可以。连接查询的一些提示。

尝试在ON 子句中使用主键,否则在此列中创建索引并避免使用* 仅选择您需要的列。如需更多信息,请改进您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2012-11-16
    • 2012-02-08
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    相关资源
    最近更新 更多