组合来自多个视图的多个SELECT查询以计算数据

时间:2011-03-30 01:06:05

标签: mysql

所以我正在尝试构建来自我已编写的几个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列。

2 个答案:

答案 0 :(得分:1)

您要找的是FULL OUTER JOIN。不幸的是,似乎没有直接在MySQL中支持,但是您可以通过执行UNIONLEFT 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来避免添加重复的行,但除此之外它非常简单。