所以我正在尝试构建来自我已编写的几个MySQL视图的报告。每个视图都有三列,看起来像这样
View ABC:
-------------------------------
| A | B | C |
| | | |
-------------------------------
| data1 | asdf | 3 |
| data1 | jkl; | 1 |
-------------------------------
假设有三个其他视图结构相同,名为DEF,GHI和JKL。在DEF视图中,最后一列名为D,在GHI中,最后一列名为E,在JKL中,最后一列名为F.
在每个视图中,A列中的值对于所有行应该是相同的(这是另一种解决我不具备的问题的方法,但我确信在那里必须是更好的方式)。
我想做的是:
View ABC:
-------------------------------------------------------------
| A | B | C | D | E | F |
| | | | | | |
-------------------------------------------------------------
| data1 | asdf | 3 | 0 | 2 | 7 |
| data1 | jkl; | 1 | 1 | 0 | 0 |
| data2 | lmno | 0 | 1 | 2 | 17 |
-------------------------------------------------------------
所以我的第一个想法是在B字段上LEFT OUTER JOIN,就像这样:
SELECT ABC.*, DEF.D, GHI.E, JKL.F
FROM ABC
LEFT OUTER JOIN DEF ON ABC.B = DEF.B
LEFT OUTER JOIN GHI ON ABC.B = GHI.B
LEFT OUTER JOIN JKL ON ABC.B = JKL.B
这一切都很好;它用NULL填充零,我可以很容易地将其COALESCE转换为0.但问题是,如果DEF,GHI或JKL视图中有一行,其中用户名与ABC中的用户名不匹配;我的SELECT中省略了该行(由于这是一个LEFT OUTER JOIN)。 RIGHT OUTER JOIN遇到同样的问题。
有没有办法执行完全外部连接,以便在四个视图中的任何一个中出现的任何B在我的SELECT中都有一行?我已经尝试嵌入其他一些选择,但不幸的是,这似乎在SELECT的结果中以不可接受的方式重复行和数据值。从查看文档,我不认为MySQL支持完全外连接(至少不是我能找到的),即使它确实如此,我也不知道如何从其他视图中获取用户名到SELECT语句中的username列。
答案 0 :(得分:1)
您要找的是FULL OUTER JOIN。不幸的是,似乎没有直接在MySQL中支持,但是您可以通过执行UNION
和LEFT JOIN
的{{1}}来实现结果。
来自:http://dev.mysql.com/doc/refman/5.0/en/join.html
发布者:barbarina于2006年9月12日下午2:17
您可以使用模拟FULL OUTER JOIN UNION(来自MySQL 4.0.0):
有两个表t1,t2:
RIGHT JOIN
有三个表t1,t2,t3:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id
答案 1 :(得分:0)
所以Adam Franco的解决方案实际上非常接近,除了他们都使用LEFT OUTER JOIN而不是LEFT和RIGHT的组合。鉴于我必须使用UNION,所有列必须按顺序匹配,因此LEFT和RIGHT OUTER JOIN的组合已经完成。在根据他的建议考虑UNION之后,我设法凑齐了这个:
SELECT ABC.B, ABC.C, DEF.D, GHI.E, JKL.F
FROM ABC
LEFT OUTER JOIN DEF ON DEF.B = ABC.B
LEFT OUTER JOIN GHI ON ABC.B = GHI.B
LEFT OUTER JOIN JKL ON JKL.B = ABC.B
UNION DISTINCT
SELECT DEF.B, ABC.C, DEF.D, GHI.E, JKL.F
FROM `DEF`
LEFT OUTER JOIN ABC ON DEF.B = ABC.B
LEFT OUTER JOIN GHI ON DEF.B = GHI.B
LEFT OUTER JOIN JKL ON JKL.B = DEF.B
UNION DISTINCT
SELECT GHI.B, ABC.C, DEF.D, GHI.E, JKL.F
FROM `GHI`
LEFT OUTER JOIN ABC ON GHI.B = ABC.B
LEFT OUTER JOIN DEF ON DEF.B = GHI.B
LEFT OUTER JOIN JKL ON JKL.B = GHI.B
UNION DISTINCT
SELECT ABC.B, ABC.C, DEF.D, GHI.E, JKL.F
FROM `ABC`
LEFT OUTER JOIN DEF ON DEF.B = ABC.B
LEFT OUTER JOIN GHI ON ABC.B = GHI.B
LEFT OUTER JOIN JKL ON JKL.B = ABC.B
UNION DISTINCT
SELECT DEF.B, ABC.D, DEF.D, GHI.E, JKL.F
FROM `DEF`
LEFT OUTER JOIN ABC ON DEF.B = ABC.B
LEFT OUTER JOIN GHI ON DEF.B = GHI.B
LEFT OUTER JOIN JKL ON JKL.B = DEF.B
UNION DISTINCT
SELECT JKL.B, ABC.D, DEF.D, GHI.E, JKL.F
FROM `JKL`
LEFT OUTER JOIN ABC ON JKL.B = ABC.B
LEFT OUTER JOIN DEF ON DEF.B = JKL.B
LEFT OUTER JOIN GHI ON JKL.B = GHI.B
我不得不使用UNION DISTINCT来避免添加重复的行,但除此之外它非常简单。