怀疑但不确定:
FROM
- 子句中的表的简单列表是按定义完全连接吗?
SELECT *
FROM table1, table2
并且我们在不相等的参数条件下连接表是否是完全外连接的实现? E.g:
SELECT *
FROM table1
JOIN table2
ON table1.id <> table2.id
到目前为止我发现了更多细节:
“CROSS JOIN
会返回笛卡尔积”http://en.wikipedia.org/wiki/Join_(SQL)
可以通过以下方式指定要加入的表的列表:
“Table1, Table2, Table3,...
这是最简单的形式。这些表以MySQL认为最有效的方式连接在一起。此方法也可以写为表1 JOIN Table2 JOIN Table3,...
也可以使用CROSS
关键字,但它没有效果(例如,Table1 CROSS JOIN Table2
)只包含符合两列条件的行在联合表中。“
MySQL袖珍参考,第二版由George Reese
所以,第一个看起来似乎是CROSS JOIN
表或笛卡尔积。
答案 0 :(得分: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 演示。此演示还包括您的查询。查看结果集的差异。
答案 1 :(得分:1)
让我们检查你的第二个问题:
作为一个例子,我们使用下表:
-- t1
id name
1 Tim
2 Marta
-- t2
id name
1 Tim
3 Katarina
重要提示:并非表t1中存在表t1的所有主键,反之亦然!
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`;