2011-03-30 48 views
0

所以我试图从我已经编写的几个MySQL视图构建一个报表。每个视图一个有三列,看起来像这样结合多个视图中的多个SELECT查询来统计数据

View ABC: 
------------------------------- 
| A | B | C | 
|   |   |   | 
------------------------------- 
| data1 | asdf | 3 | 
| data1 | jkl; | 1 | 
------------------------------- 

假设有其相同结构的其他三个视图,命名为DEF,GHI和JKL。在DEF中,最后一列命名为D,在GHI中最后一列命名为E,在JKL中最后一列命名为F.

在每个视图中,A列中的值应该相同对于所有行(这是另一种解决我所遇到的问题的方法,它不完全依赖于MySQL,但我确定必须有更好的方法)。

我想要做的是这样的:

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 | 
------------------------------------------------------------- 

所以,我首先想到的是LEFT OUTER JOIN在B场,就像这样:

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中简单地省略(因为这是一个左外连接)。 RIGHT OUTER JOIN遭受同样的问题。

有没有办法执行一个完整的外连接,使得在任何四个视图中出现的任何B在我的SELECT中都有一行?我试过嵌入一些其他选择,但不幸的是,似乎在SELECT的结果中以不可接受的方式重复行和数据值。从查看文档,我不认为MySQL支持一个完整的外连接(至少不是我能找到的),即使这样做,我也不知道如何从其他视图获取用户名到SELECT语句中的用户名列。

回答

1

你在找什么叫做FULL OUTER JOIN。不幸的是,它似乎并没有直接支持MySQL,但是您可以通过执行UNIONLEFT JOIN s和RIGHT JOIN s来获得结果。

来源:http://dev.mysql.com/doc/refman/5.0/en/join.html

发布者Barbarina酒店于2006年下午2点17

9月12日,您可以模拟全外使用(从MySQL 4.0.0上) UNION JOIN:

带两张表t1,t2:

SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id 
UNION 
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id 

三用表T1,T2,T3:

SELECT * 
FROM 
    t1 
    LEFT JOIN t2 ON t1.id = t2.id 
    LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * 
FROM t1 
    RIGHT JOIN t2 ON t1.id = t2.id 
    LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * 
FROM 
    t1 
    RIGHT JOIN t2 ON t1.id = t2.id 
    RIGHT JOIN t3 ON t2.id = t3.id 
+0

再想一想,我想我得出的结论是,一个完整的外部连接实际上不是要走的路,我被迫执行多个选择并将它们联合在一起。使用这个逻辑,我能够产生最终的查询(我将在另一个答案中发布,因为这个评论太长了)。 – wibarr 2011-03-30 01:38:11

0

所以亚当佛朗哥的解决方案实际上是相当接近,但它们都使用LEFT OUTER连接,而不是左,右的组合。鉴于我不得不使用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以避免被添加重复行,但除此之外,这是非常简单的。