关于连接的澄清

问题描述 投票:0回答:3

在 Oracle,我被教导要加入 as

select * 
from Table_a a, Table_b b, Table_c c
where a.id = b. Id and b.thing = c.thing 

我正在使用这种方法,忽略了我遵循的进行显式连接的培训,因为我公司的每个人都使用上述方法。

现在我们已经迁移到 SQL Server(Azure 数据工作室),现在我正在使用

select *
from Table_a a 
join Table_b b on a.id = b.id
join Table_c c on b.thing = c.thing

对于内部连接,我完全明白这一点。

令我困惑的是,当我将其更改为如下所示的左连接时

select *
from Table_a a 
left join Table_b b on a.id = b.id
left join Table_c c on b.thing = c.thing

我了解左连接是什么,但我很难理解连接的工作原理。我是否告诉它 - 使用 a 中的所有记录,然后在没有找到任何内容时返回表 b 中的所有值(带空) - 那么我遇到的问题是与 c 的联接。我是否使用表 a 作为基础,以便查找 a 中的所有值,然后查找 c 中匹配的任何值作为空值?

如果 a 到 b 是内连接,而 c 是左连接,会发生什么? c 是否左连接到 b?或者离开加入a?

下面的例子

select *
from Table_a a 
join Table_b b on a.id = b.id
left join Table_c c on b.thing = c.thing

我是否在这种情况下告诉它,我希望左连接仅到 b,所以我只在 a 中查找记录,全部在 b 中查找,并在 c 中匹配带有空值的值?

我可能没有任何意义,因为很难解释我的意思,但简而言之,如果我使用所有左连接,我就会明白会发生什么,但如果它们混合并匹配,我就无法理解它。预先感谢您的任何评论

我试图理解左连接和内连接的混合如何组合。

sql sql-server left-join
3个回答
0
投票

尝试一切并查看结果可能是最简单的:

CREATE TABLE a (id int, col1 varchar(10));
CREATE TABLE b (id int, col1 varchar(10));
CREATE TABLE c (id int, col1 varchar(10));

INSERT INTO a (id, col1) VALUES (1, 'a1'), (2, 'a2'),(3, 'a3');
INSERT INTO b (id, col1) VALUES (1, 'b1'), (2, 'b2'),(4, 'b4');
INSERT INTO c (id, col1) VALUES (1, 'c1'), (3, 'c3'),(4, 'c4');

SELECT *
FROM a
  LEFT OUTER JOIN b 
     ON a.id = b.id
  LEFT OUTER JOIN c
     ON b.id = c.id;

+----+------+------+------+------+------+
| id | col1 |  id  | col1 |  id  | col1 |
+----+------+------+------+------+------+
|  1 | a1   | 1    | b1   | 1    | c1   |
|  2 | a2   | 2    | b2   | null | null |
|  3 | a3   | null | null | null | null |
+----+------+------+------+------+------+

在所有

LEFT OUTER JOIN
的查询中,选择
a
中的所有记录,然后仅选择
b
中的匹配记录,最后仅选择
c
中与上一次连接中幸存下来的
b
记录相匹配的记录它通过了。


SELECT *
FROM a
  INNER JOIN b 
     ON a.id = b.id
  LEFT OUTER JOIN c
     ON b.id = c.id;

+----+------+----+------+------+------+
| id | col1 | id | col1 |  id  | col1 |
+----+------+----+------+------+------+
|  1 | a1   |  1 | b1   | 1    | c1   |
|  2 | a2   |  2 | b2   | null | null |
+----+------+----+------+------+------+

将第一个连接切换为

INNER JOIN
会导致输出出现机会。现在记录必须在
a
b
之间匹配才能在 INNER JOIN 中生存。然后,只有
c
中与
b
剩余内容匹配的记录才会带入其值。

您可以在此处查看此操作:https://dbfiddle.uk/3pB_Rb_3


0
投票

逐步考虑联接:第一次联接后,您会得到一些中间表,然后将第三个表 C 联接到该表上


0
投票

记住你的正式关系代数是有帮助的,我们所认为的表格是表达正式所谓的“关系”的一种方式。 在这种情况下,连接两个关系(A 和 B)的结果是另一个关系。

我遇到的困难是加入 c。我是否使用表 a 作为基础,以便查找 a 中的所有值,然后查找 c 中匹配的任何值作为空值?

不。您可以将其视为将 C 连接到 A + B 连接的结果。毕竟,A 加入 B 只是另一种关系。

现实中,事情可能并非如此。数据库会尽可能走捷径,以提高效率和性能,并且如果数据库认为新顺序仍然准确且性能更好,有时可以自由地重新排序您的 JOIN。但从语义上讲,您可以将其视为联接操作从上到下或从左到右工作,具体取决于您设置查询的格式。

哦,当然也取决于你如何构建括号或嵌套。如果您认为 A join B join C 不好,请等到您看到类似

A JOIN (B JOIN C ON ...) ON ...

 的内容
    

© www.soinside.com 2019 - 2024. All rights reserved.