0

怀疑但不确定:FROM-clause 中的简单表列表是否定义为完全连接?

SELECT * 
FROM table1, table2 

并且我们在不相等参数的条件下连接表的情况是否是完全外部连接的实现?例如:

SELECT * 
FROM table1
JOIN table2
ON table1.id <> table2.id 

到目前为止,我发现了更多细节:

CROSS JOIN返回笛卡尔积” http://en.wikipedia.org/wiki/Join_(SQL)

可以通过以下方式指定要连接的表列表: "这是最简单的形式。表以 MySQL 认为最有效的方式连接。这种Table1, Table2, Table3,... 方法也可以写成 Table1关键字也可以使用,但是它没有效果(例如,)只有与两列的条件匹配的行才会包含在连接表中。” MySQL Pocket Reference,第二版,George ReeseJOIN Table2 JOIN Table3,...CROSSTable1 CROSS JOIN Table2

所以,第一个似乎真的是一个CROSS JOIN表,或者一个笛卡尔积。

在此处输入图像描述

4

2 回答 2

1

MySQL 仍然缺乏对FULL JOIN. 模仿它的一种方法

SELECT a.id id0, t1.id id1, t2.id id2
  FROM
(
  SELECT id
    FROM table1
  UNION
  SELECT id
    FROM table2
) a LEFT JOIN table1 t1
   ON a.id = t1.id LEFT JOIN table2 t2
   ON a.id = t2.id;

这是SQLFiddle演示。此演示还包括您的两个查询。查看结果集的差异。

于 2013-11-06T03:13:26.777 回答
1

让我们检查您的第二个查询:

例如,我们使用下表:

-- t1
id  name
1   Tim
2   Marta

-- t2
id  name
1   Tim
3   Katarina

重要提示:并非表 t1 的所有主键都存在于表 t2 中,反之亦然!

CREATE TABLE `t1` (
  `id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `t2` (
  `id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `t1` VALUES (1,'Tim'),(2,'Marta');
INSERT INTO `t2` VALUES (1,'Tim'),(3,'Katarina');

现在我们运行您的查询:

SELECT * 
FROM t1
JOIN t2
ON t1.id <> t2.id 

结果集是:

id    name   id   name
===========================
2     Marta  1    Tim
1     Tim    3    Katarina
2     Marta  3    Katarina

发生了什么?您选择了所有不匹配的组合!

让我们看一下 FULL OUTER JOIN 的定义:

FULL OUTER JOIN结合了左外连接和右外连接的结果,并从表两侧的表中返回所有(匹配或不匹配的)行。

好的,我们还需要左右外连接的定义:

LEFT OUTER JOIN返回左表中的所有记录,而不考虑与右表的匹配。

RIGHT OUTER JOIN返回右表中的所有记录,而不考虑与左表的匹配。

让我们手动执行此操作:

LEFT OUTER JOIN 从左表返回 Tim 和 Marta,其中 Tim 作为唯一匹配项:

id    name   id   name
===========================
1     Tim    1    Tim
2     Marta  NULL NULL

RIGHT OUTER JOIN 从右表返回 tim 和 katarina,其中 Tim 作为唯一匹配项:

id    name   id   name
===========================
1     Tim    1    Tim
NULL  NULL   3    Katarina

如果我们将这两者结合到一个 FULL OUTER JOIN 我们得到:

id    name   id   name
===========================
1     Tim    1    Tim
2     Marta  NULL NULL
NULL  NULL   3    Katarina

这是正确的结果集。在 MySQL 中,这可以通过左右外连接的 UNION 来完成:

SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`

UNION

SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
于 2013-11-06T03:37:12.250 回答