"FROM a, b" 和 "FROM a FULL OUTER JOIN b" 有什么区别?

What is the difference between "FROM a, b" and "FROM a FULL OUTER JOIN b"?

处理来自多个 table 的数据时,您可以通过多种不同的方式 JOIN 这些 table ,每种方式都会改变匹配列的方式对待。您也可以只从 table 中提取数据,即 FROM [table a], [table b].

这个方法似乎仍然以某种方式加入 tables,如果我不得不猜测,我会说这个方法只是 shorthand for FULL OUTER JOIN,但是我敢肯定两者之间是有区别的。

区别仅仅是 FULL OUTER JOIN 之后是 ON [table 1 specific column] = [table 2 specific column],还是有其他原因?

在第一种情况下,您应用 CROSS JOIN(或 Cartersian Product)- 如果您不对 link 字段使用 WHERE 子句(在这种情况下,您有一个 INNER JOIN), 在第二种情况下你应用 FULL OUTER JOIN.

差异

对于笛卡尔积,你 link 第一行的每一行 table 和第二行的每一行 table

FULL OUTER JOIN 你 link 第一行 table 与第二行 table 但是如果关系不满足你有一个 NULL两侧.

例子

假设您有两个像这样的 table:

CREATE TABLE a (id_a int)
CREATE TABLE b (id_b int)

这些内容:

INSERT INTO A (1)
INSERT INTO A (2)

INSERT INTO B (2)
INSERT INTO B (3)

在第一种情况下,(笛卡尔积)你将有:

SELECT * FROM A, B

1 2
1 3
2 2
2 3

在第二种情况下,您将拥有:

SELECT * FROM A FULL OUTER JOIN B
ON A.ID_A = B.ID_B

1    NULL
2    2
NULL 3

如果你写:

SELECT * FROM A,B WHERE A.ID_A = B.ID_B 

与此相同:

SELECT * FROM A JOIN B ON A.ID_A = B.ID_B

结果如下:

2 2

您的问题已经得到解答,但是从您的评论中我了解到您仍然不确定您是否完全理解了这件事。所以,我想我只是添加另一个答案:-)

让我们从简单的开始

FROM a, b

这是一种过时的连接语法,在标准 SQL-1992 中被显式连接所取代。对于上述内容,您必须将连接条件(如果有)放在 WHERE 子句中。如果 WHERE 子句中没有连接条件,这是一个交叉连接,您现在可以明确地将其写为

FROM a CROSS JOIN b

这告诉 reader 您有意想要 a 和 b 的所有组合(并且不仅忘记了连接条件或错误地删除了它)。一个例子是

FROM store CROSS JOIN product

这里你把每个店铺和每个产品结合起来,不管这个店铺是否真的有这个产品;您只需显示所有可能的组合。有两家商店和两种产品,结果可能如下所示:

store   product
s1      p1
s1      p2
s2      p1
s2      p2

很少需要交叉连接。在上述情况下,我们可能想知道所有商店 product/combinations 和 select 每一行的 'yes' 或 'no',因此我们可以看到商店有哪些产品,哪些没有。

在关系数据库中,我们通常处理 table 的关系,但是,让我们添加连接条件:

FROM a, b
WHERE a.col1 = b.col2

这是一个内部联接,我们只在其中查找记录匹配项。现在写成

FROM a
INNER JOIN b ON a.col1 = b.col2

或(省略可选关键字 INNER,因为默认情况下联接是内部联接):

FROM a
JOIN b ON a.col1 = b.col2

这是一个例子。我们有两个 table 包含每个部门和每年的费用和收入。

FROM dept_cost
JOIN dept_gain ON dept_gain.dept_no = dept_cost.dept_no AND dept_gain.year = dept.cost.year

假设 table 包含:

year   dept_no   total_cost
2015   d001      20000
2016   d001      25000
2016   d002      10000

year   dept_no   total_gain
2015   d001      40000
2015   d002      30000
2016   d001      50000

那么结果将是:

year   dept_no   total_cost   total_gain
2015   d001      20000        40000
2016   d001      25000        50000

因为在bothtables.

中只找到2015/d001和d001/2016

如果你也想看到其他数据,你必须外连接。您可以将 dept_gain 外连接到 dept_cost,以便查看 所有 成本 - 以及它们的收益(如果有)。或者,反之亦然,您将 dept_cost 外部连接到 dept_gain,以便查看 所有 收益 - 以及它们的成本(如果有)。或者你full outer join,以便看到所有数据:

FROM dept_cost
FULL OUTER JOIN dept_gain ON dept_gain.dept_no = dept_cost.dept_no 
                          AND dept_gain.year = dept.cost.year
year   dept_no   total_cost   total_gain
2015   d001      20000        40000
2015   d002                   30000
2016   d001      25000        50000
2016   d002      10000        

很少需要CROSS JOIN 和FULL OUTER JOIN。因此,如果您还不了解它们,请不要担心。您通常只需要 INNER JOIN,有时需要 LEFT OUTER JOIN。