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


当前回答

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

其他回答

在简单的条件下,

1.INNER JOIN OR EQUI JOIN : 返回结果组,仅符合两张表中的状态。

2.OUTER JOIN : 从两个表中返回所有值的结果,即使有条件相匹配或不相匹配。

3.LEFT JOIN : 从左表中返回所有值的结果组合,并仅与右表中的条件相匹配的行。

4.RIGHT JOIN : 从右表返回所有值的结果组合,并且仅符合左表的条件的行列。

5、全加入:全加入和全外加入是相同的。

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

注意:在 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

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

最简单的定义

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

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

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

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

短短

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

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

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

相匹配 = 内部加入

1.内部加入:也称为加入. 它返回在左表中的两行,右表只有如果有比赛。

例子:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

此分類上一篇

2.Full Outer 加入: 也称为Full 加入. 它返回所有的行在左表和右表。

例子:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

此分類上一篇

3.Left Outer 加入: 或者简单地称为Left 加入. 它返回左表中的所有行,并从右表中匹配行(如有)。

右外加入:也称为右加入. 返回相匹配的行从桌面左(如果有),并所有行在桌面右。

此分類上一篇

加入的好处

更快的执行

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

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

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

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

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