1、问题概述
在 MySQL 中,不支持 FULL OUTER JOIN 的语法,但我们可以通过其他方式来实现 FULL OUTER JOIN的效果。FULL OUTER JOIN 是一种联结方式,它返回两个表的所有匹配行和非匹配行。此篇博客介绍一种使用 UNION 和 LEFT JOIN、RIGHT JOIN 来实现 FULL OUTER JOIN 的方法。
2、实现方法
现在拿两个表来解释,表1是网站表(website)主要是id、网站名称、网站地址、排名和所属国家。表2是访问日志表(access_log),主要是id、网站id、访问次数和日期。
表1:website(网站表)
表2:access_log(访问日志表)
从表中可以看出,表1的网站表,没有id为7的,而表2的site_id是有id为7的数据,但是没有site_id为6的。
SELECT * FROM websites w
LEFT JOIN access_log a on w.id = a.site_id
UNION
SELECT * FROM websites w
RIGHT JOIN access_log a on w.id = a.site_id
输出结果如下,虽然access_log表没有id为6的,但是结果还会有id为6的一行数据,只是access_log表对应的各个数据项为null。虽然website表没有id为7的,但是结果还会有site_id为7的一行数据,但是website表的数据项为null。
3、总结
通过以上步骤,可以使用 UNION 和 LEFT JOIN、RIGHT JOIN 来实现 MySQL 中没有直接支持的 FULL OUTER JOIN。通过组合这些操作,我们可以获得两个表的所有匹配行和非匹配行。
4、union用法注意
-
1、使用UNION命令时需要注意,只能在最后使用一个ORDER BY命令,是将两个查询结果合在一起之后,再进行排序!绝对不能写两个ORDER BY命令。另外,在使用ORDER BY排序时,注意两个结果的别名保持一致,使用别名排序很方便。当然也可以使用列数。
-
2、ORDER BY 只能当前 SQL 查询结果进行排序,如要对 union all 出来的结果进行排序,需要先做集合。如下代码所示:
select aa.* from
(select country,name from websites where country = 'CN'
union all select country,app_name from apps where country='CN' ) aa
order by aa.name;