此外,如何适应左外加入,右外加入和全外加入?


当前回答

“外部”和“内部”只是可选的元素,你只是处理两个(三个)类型的加入。内部加入(或什么是默认使用只有“加入”)是一个加入,只有符合标准的元素在两个表上存在。

“外部”插件是相同的内部插件加上不匹配的左或右表的元素,并在其他表的所有列上添加零。

全合是内合,右合和左合。

总之,如果我们有这样的表A

idA ColumnTableA idB
1 Jonh 1
2 Sarah 1
3 Clark 2
4 Barbie NULL

图B如下:

idB ColumnTableB
1 Connor
2 Kent
3 Spock

内部加入:

from tableA join tableB on tableA.idB = tableB.idB
idA ColumnTableA idB ColumnTableB
1 Jonh 1 Connor
2 Sarah 1 Connor
3 Clark 2 Kent

左边加入:

from tableA left join tableB on tableA.idB = tableB.idB
idA ColumnTableA idB ColumnTableB
1 Jonh 1 Connor
2 Sarah 1 Connor
3 Clark 2 Kent
4 Barbie NULL NULL

向外加入:

from tableA right join tableB on tableA.idB = tableB.idB
idA ColumnTableA idB ColumnTableB
1 Jonh 1 Connor
2 Sarah 1 Connor
3 Clark 2 Kent
NULL NULL 3 Spock

全外加入:

from tableA full join tableB on tableA.idB = tableB.idB
idA ColumnTableA idB ColumnTableB
1 Jonh 1 Connor
2 Sarah 1 Connor
3 Clark 2 Kent
4 Barbie NULL NULL
NULL NULL 3 Spock

其他回答

我在其他答案中看不到很多关于性能和优化的细节。

有时,知道只有INNER JOIN是合并的,这意味着优化器有最多的选择与它一起玩,它可以重新订单加入顺序,使它更快地保持相同的结果,优化器可以使用最多加入模式。

一般来说,尝试使用 INNER JOIN 而不是不同类型的插件是很好的做法(当然,如果可以考虑到预期的结果设置)。

这里有几个好例子和解释这个奇怪的协会行为:

是否留在外部合并合并合并?合并命令在SQL中的内容?

INNER JOIN 要求在比较两个表中至少有一场比赛. 例如,表 A 和表 B 意味着 A 8 B (A 交叉点 B)。

LEFT OUTER JOIN 和 LEFT JOIN 是相同的. 它提供所有相匹配的记录在两张桌子和所有选项的左桌子。

同样,RIGHT OUTER JOIN和RIGHT JOIN是相同的,它提供了所有记录相匹配的两张表和所有可能的正确的表。

FULL JOIN 是 LEFT OUTER JOIN 和 RIGHT OUTER JOIN 无重复的组合。

一次示威

设置

跳进 psql 并创建一个小数据库的猫和人类. 你可以只是复制这个整个部分。

CREATE DATABASE catdb;
\c catdb;
\pset null '[NULL]' -- how to display null values

CREATE TABLE humans (
  name text primary key
);
CREATE TABLE cats (
  human_name text references humans(name),
  name text
);

INSERT INTO humans (name)
VALUES ('Abe'), ('Ann'), ('Ben'), ('Jen');

INSERT INTO cats (human_name, name)
VALUES
('Abe', 'Axel'),
(NULL, 'Bitty'),
('Jen', 'Jellybean'),
('Jen', 'Juniper');

求求

SELECT
humans.name AS human_name,
cats.name AS cat_name
FROM humans
[SOMETHING JOIN] cats ON humans.name = cats.human_name
ORDER BY humans.name;

任何人,没有猫或猫,没有人,都被排除在外。

 human_name | cat_name
------------+-----------
 Abe        | Axel
 Jen        | Jellybean
 Jen        | Juniper

A FULL OUTER JOIN returns all humans and all cats, with zero if there is no match on both sides. 全外加入将返回所有人类和所有猫,如果双方都没有比赛,则零。

 human_name | cat_name
------------+-----------
 Abe        | Axel
 Ann        | [NULL]
 Ben        | [NULL]
 Jen        | Jellybean
 Jen        | Juniper
 [NULL]     | Bitty

 human_name | cat_name
------------+-----------
 Abe        | Axel
 Ann        | [NULL]
 Ben        | [NULL]
 Jen        | Jellybean
 Jen        | Juniper

每只猫,没有人,都会在人名列中获得零;每只猫,没有人,都会被排除。

 human_name | cat_name
------------+-----------
 Abe        | Axel
 Jen        | Jellybean
 Jen        | Juniper
 [NULL]     | Bitty

你可以看到,虽然一个内部加入只获得匹配夫妇,每个类型的外部加入包括一些没有比赛的项目。

加入本身意味着内部左加入,右加入和外加入,所有意味着外加入。

内部加入需要附加表中包含相关 ID 的记录。

外部连接将为左侧返回记录,即使没有对右侧的记录。

例如,您有一个订单和一个订单细节表,它们由一个“订单ID”相关。

命令

客戶名稱

命令细节

商品名稱 Qty 價格

请求

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

只会返回订单,该订单还包含在订单详细信息表中的一些东西。

如果您将其更改为向左加入

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

然后它将从订单表中返回记录,即使它们没有订单详细记录。

您可以使用此来查找没有订单详细信息的订单,并通过添加一个在哪里条款,如Where OrderDetails.OrderID IS NULL。

您使用 INNER JOIN 返回两个表中的所有行,即在结果表中,所有行和列都将有值。

在 OUTER JOIN 中,结果表可能有空列,外部加入可能是左或右。

LEFT OUTER JOIN 从第一张桌子中返回所有行,即使在第二张桌子中没有比赛。

RIGHT OUTER JOIN 从第二张桌子返回所有行,即使在第一张桌子上没有比赛。