除非您想要右侧有一行但左侧没有匹配行的行的 NULL 值(即RIGHT JOIN),否则听起来您想要一个“INNER JOIN”。但是,如果JOIN 条件匹配多行,您将在结果中获得多行。以下是它的工作原理:
- 找到左边的东西(查询中
INNER JOIN之前指定的表),
- 找到右边的东西(查询中
INNER JOIN后面指定的表),
- 接下来,根据指定条件(在
ON 之后指定)从每一侧匹配行,
- 如果对于左侧的一个匹配行,右侧有一个匹配的行,则将左侧行的列值与列值放在一起从右表到结果中的一行
- 如果任一侧有多个匹配行,则从每一侧复制每一行,以便结果具有所有可能的匹配组合,并将它们放入结果中。李>
如果来自任一侧的单行数据多次显示在结果中,那只能是因为用于JOIN 的条件(ON 子句之后的条件)导致多行一侧匹配另一侧的一行或多行。
例如,如果我有以下两个表:
Table1 | Key | Value
------ | --- | -----
| 1 | A1
| 1 | A2
| 2 | B
| 3 | C
| 5 | E
Table2 | Key | Value
------ | --- | -----
| 1 | Z
| 2 | Y
| 3 | X1
| 3 | X2
| 4 | W
以下查询:
SELECT * FROM Table1 first
RIGHT JOIN Table2 second ON first.Key=second.Key
将返回以下结果:
Table2 | Key | Value | Key | Value
------ | --- | ----- | --- | -----
| 1 | A1 | 1 | Z
| 1 | A2 | 1 | Z
| 2 | B | 2 | Y
| 3 | C | 3 | X1
| 3 | C | 3 | X2
|NULL | NULL | 4 | W
请注意,Table2 中的 1,Z 行在结果中出现了两次,而 A 中的 3,C 行也出现了两次。 4,W 出现是因为它是RIGHT JOIN。 LEFT JOIN 会将 5,E 放入结果中,而 INNER JOIN(或只是简单的 JOIN)将没有这些行。 OUTER JOIN 将包含这两行。
如果 Table2 有两个键为 1 的条目(例如 Z1 和 Z2),则键为 1 的结果将有四个(一个为 A1、Z1,一个为 A2、Z1,一个为 A1、Z2,以及一个与 A2,Z2)。这是事情真正膨胀的地方,从你的数字来看,你可能有几个关键值就是这种情况。
如果 Table1 和 Table2 中的值都有相同的键值,则结果集将包含所有可能的值组合,因此结果集中的行数将是 Table1 中的行数 次 Table2 的行数。
WHERE 子句中的限制也可能会修剪与此处指定的所有条件不匹配的结果行。
对于INNER JOIN,除非在上面的步骤 4 中有多个匹配项,否则结果集中的行数不会超过源表中较小的一个。如果要确保只有一个匹配项,则两个表都必须具有唯一键(任何给定键只能有一行的键),您必须更改 ON 条件以将匹配限制为一行,或者您必须过滤 JOIN 的一侧,使其仅包含您要加入的行。