OUTER JOIN和FULL OUTER加入最简单的实现?

时间:2013-11-06 02:56:56

标签: mysql join outer-join

怀疑但不确定: 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表或笛卡尔积。

enter image description here

2 个答案:

答案 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`;