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


当前回答

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

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

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

总之,如果我们有这样的表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,LEVT/RIGHT OUTER JOIN的准确算法如下:

從第一個表中取出每個行: a 考慮從第二個表中取出所有行: (a,b[i]) 評估對每個對方的 ON... 條件: ON(a,b[i] = 真實/錯誤? 當條件評估為真實時,返回相結合的行(a,b[i])。

... ON T1.title = T2.title AND T1.version < T2.version ( => see this post as a sample use: Select only rows with max value on a column)... ON T1.y IS NULL... ON 1 = 0 (just as sample)

此分類上一篇


此分類上一篇

注意:左加入 = 左外加入,右加入 = 右外加入。

一个内部合并只显示行,如果在合并的另一边(右)有一个匹配记录。

一(左)外部连接显示在左侧的每个记录的行列,即使连接的另一(右)侧没有匹配行列,如果没有匹配行列,对另一(右)侧的列将显示零。

答案在每个人的意义上,所以在结果中。

注意:在 SQLite 中没有 RIGHT OUTER JOIN 或 FULL OUTER JOIN. 而且在 MySQL 中也没有 FULL OUTER JOIN。

我的答案是基于上面的笔记。

如果你有兩個桌子,如下:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTER JOIN : 您可以使用 CROSS JOIN 或仅仅使用,如下:

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

INNER JOIN : 如果您想根据表1.id = 表2.id 等关系添加过滤器,您可以使用 INNER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

左 [外] 加入 : 如果您希望在上面的结果中包含一个表中的所有行 - 相同的关系 - 您可以使用左加入: (为右加入,只需更改表的位置)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

FULL OUTER JOIN : 如果您也希望在您的结果中包含其他表中的所有行,您可以使用 FULL OUTER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

好吧,作为你的需要,你选择每一个覆盖你的需要。

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

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

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

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

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

内部加入需要附加表中包含相关 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。