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


当前回答

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

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

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

总之,如果我们有这样的表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

其他回答

批评了我非常喜欢的红色阴影的Venn图表,我认为发表我自己的尝试是公平的。

虽然 @Martin Smith 的答案在很长一段时间内是这个集合中最好的,但他的单一显示每个桌子的关键列,而我认为理想的非关键列也应该显示。

在允许的半小时内我能做的最好,我仍然不认为它足够地表明,由于TableB中缺乏关键值,零值存在,或者外加入实际上是一个联盟而不是一个联盟:

此分類上一篇

加入更容易用一个例子来解释:

此分類上一篇

模拟在单独的表中存储的人和电子邮件,

表 A 和表 B 由表_A.id = 表_B.name_id 添加

内部加入

此分類上一篇

只显示相匹配的IDS行。

外面加入

此分類上一篇

表 A 的匹配 ID 和不匹配行显示。

此分類上一篇

显示表 B 的匹配 ID 和不匹配行。

相匹配的ID和不相匹配的行从两个表显示。

注意:在 MySQL 上不存在完整的外部加入

最简单的定义

内部加入:从两个表中返回相匹配的记录。

Full Outer 加入:从两个表中返回相匹配和未相匹配的记录,从两个表中返回未相匹配的记录为零。

左外加入:只从左侧的桌子上返回匹配和不匹配的记录。

右外加入:只从右侧的桌子上返回相匹配和不相匹配的记录。

短短

相匹配 + 左不相匹配 + 右不相匹配 = 全外加入

相匹配 + 左不相匹配 = 左外加入

相匹配 + 相匹配不相匹配 = 相匹配不相匹配

相匹配 = 内部加入

这些两个表构成了下面的 JOIN 代表性的基础:

SELECT *
  FROM citizen
 CROSS JOIN postalcode

此分類上一篇

SELECT *
  FROM citizen    c
  JOIN postalcode p ON c.postal = p.postal

左上加入与左上加入相同

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal

游戏的数据

CREATE TABLE citizen (id      NUMBER,
                      name    VARCHAR2(20),
                      postal  NUMBER,  -- <-- could do with a redesign to postalcode.id instead.
                      leader  NUMBER);

CREATE TABLE postalcode (id      NUMBER,
                         postal  NUMBER,
                         city    VARCHAR2(20),
                         area    VARCHAR2(20));

INSERT INTO citizen (id, name, postal, leader)
              SELECT 1, 'Smith', 2200,  null FROM DUAL
        UNION SELECT 2, 'Green', 31006, 1    FROM DUAL
        UNION SELECT 3, 'Jensen', 623,  1    FROM DUAL;

INSERT INTO postalcode (id, postal, city, area)
                 SELECT 1, 2200,     'BigCity',         'Geancy'  FROM DUAL
           UNION SELECT 2, 31006,    'SmallTown',       'Snizkim' FROM DUAL
           UNION SELECT 3, 31006,    'Settlement',      'Moon'    FROM DUAL  -- <-- Uuh-uhh.
           UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space'   FROM DUAL;

与加入和在哪里玩时的混乱边界

SELECT *
  FROM citizen          c
  CROSS JOIN postalcode p
 WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows

INNER JOIN成为一个卡特西亚产品,它与The General Idea/CROSS JOIN相同:

SELECT *
  FROM citizen    c
  JOIN postalcode p ON 1 = 1  -- < -- The ON condition makes it a CROSS JOIN

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal
 WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode

十字路口加入

此分類上一篇

试图像这样代表它:

内心加入

SELECT *
  FROM citizen c1
  JOIN citizen c2 ON c1.id = c2.leader

外面加入

此分類上一篇

哪里条款 - 做意义

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   AND p.area = 'Moon';

此分類上一篇

而且,这就有意义了。

兴趣

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
INTERSECT
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

联盟

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
UNION
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

相当于:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   OR p.area = 'Moon';

...并给出结果:

此外,这里有一个Venn图表有意义:

此分類上一篇

SELECT *
  FROM citizen
 WHERE name = 'Smith'
SELECT *
  FROM postalcode
 WHERE area = 'Moon';

试图将结果与联合会相结合,提供一个

ORA-01790: expression must have same datatype as corresponding expression

简单的说法:

一个内部合并只接收相匹配的行列。

虽然一个外部加入从一个表中获取相匹配的行,而在另一个表中的所有行......结果取决于你使用哪个行:

左: 右桌上的匹配行和左桌上的所有行 右: 左桌上的匹配行和右桌上的所有行 或 完整: 所有桌上的所有行。