在 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 中匹配带有空值的值?
我可能没有任何意义,因为很难解释我的意思,但简而言之,如果我使用所有左连接,我就会明白会发生什么,但如果它们混合并匹配,我就无法理解它。预先感谢您的任何评论
我试图理解左连接和内连接的混合如何组合。
尝试一切并查看结果可能是最简单的:
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
逐步考虑联接:第一次联接后,您会得到一些中间表,然后将第三个表 C 联接到该表上
记住你的正式关系代数是有帮助的,我们所认为的表格是表达正式所谓的“关系”的一种方式。 在这种情况下,连接两个关系(A 和 B)的结果是另一个关系。
我遇到的困难是加入 c。我是否使用表 a 作为基础,以便查找 a 中的所有值,然后查找 c 中匹配的任何值作为空值?
不。您可以将其视为将 C 连接到 A + B 连接的结果。毕竟,A 加入 B 只是另一种关系。
现实中,事情可能并非如此。数据库会尽可能走捷径,以提高效率和性能,并且如果数据库认为新顺序仍然准确且性能更好,有时可以自由地重新排序您的 JOIN。但从语义上讲,您可以将其视为联接操作从上到下或从左到右工作,具体取决于您设置查询的格式。
哦,当然也取决于你如何构建括号或嵌套。如果您认为 A join B join C 不好,请等到您看到类似
A JOIN (B JOIN C ON ...) ON ...
的内容