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


当前回答

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

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

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

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

其他回答

假设你加入没有复制的列,这是一个非常常见的案例:

A 和 B 的内部结合会产生 A 交叉B 的结果,即 Venn 图表交叉的内部部分; A 和 B 的外部结合会产生 A 联盟 B 的结果,即 Venn 图表联盟的外部部分。

例子

假设你有两个表,每个单列,并数据如下:

A    B
-    -
1    3
2    4
3    5
4    6

内部加入

使用相同的查询中的任何一个内部连接提供两张表的交叉,即它们共通的两行。

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

a | b
--+--
3 | 3
4 | 4

左边加入

左向外加入将提供A中的所有行,加上B中的任何常见行。

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4

向外加入

一个正确的外部加入将给所有行在B,加上任何常见行在A。

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6

全外加入

一个完整的外部加入会给你A和B的联盟,即A中的所有行和B中的所有行,如果A中的任何东西没有相应的日期在B,那么B部分是零,反之亦然。

select * from a FULL OUTER JOIN b on a.a = b.b;

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5

EmpID EmpName
13 Jason
8 Alex
3 Ram
17 Babu
25 Johnson

位置

EmpID EmpLoc
13 San Jose
8 Los Angeles
3 Pune, India
17 Chennai, India
39 Bangalore, India

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

Employee.EmpId Employee.EmpName Location.EmpId Location.EmpLoc
13 Jason 13 San Jose
8 Alex 8 Los Angeles
3 Ram 3 Pune, India
17 Babu 17 Chennai, India

左外加入:- 对员工和位置表的左外加入(或仅仅是左外加入)的结果总是包含“左”表(员工)的所有记录,即使加入条件在“右”表(位置)中找不到任何匹配记录。

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

Employee.EmpId Employee.EmpName Location.EmpId Location.EmpLoc
13 Jason 13 San Jose
8 Alex 8 Los Angeles
3 Ram 3 Pune, India
17 Babu 17 Chennai, India
25 Johnson NULL NULL

右外登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

使用上面的表,我们可以显示一个正确的外部加入的结果设置会是什么样子:

Employee.EmpId Employee.EmpName Location.EmpId Location.EmpLoc
13 Jason 13 San Jose
8 Alex 8 Los Angeles
3 Ram 3 Pune, India
17 Babu 17 Chennai, India
NULL NULL 39 Bangalore, India

请注意,虽然没有员工被列为在巴格罗尔工作,但它仍然被列入结果中,员工字段被删除。

Employee.EmpId Employee.EmpName Location.EmpId Location.EmpLoc
13 Jason 13 San Jose
8 Alex 8 Los Angeles
3 Ram 3 Pune, India
17 Babu 17 Chennai, India
25 Johnson NULL NULL
NULL NULL 39 Bangalore, India

Oracle 加入活动

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

此分類上一篇

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

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

内部加入

此分類上一篇

只显示相匹配的IDS行。

外面加入

此分類上一篇

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

此分類上一篇

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

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

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

这些两个表构成了下面的 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

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)

此分類上一篇


此分類上一篇

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