如何在mysql中使用同一个表和不同组的联合查询?

时间:2012-02-28 00:07:34

标签: mysql group-by union

我有这样的SQL查询:

select a.x, a.y, sum(a.foo) as foo_sum
from a
group by a.x

运行此查询后,我可以访问foo_sum。

我想做这样的事情:

select a.x, a.y, sum(a.foo) as foo_sum
from a
group by a.x
union
select a.x, a.y, sum(a.bar) as bar_sum
from a
group by a.y

但是在运行这个之后,我的程序知道foo_sum,有人知道为什么吗?

谢谢。

编辑:我希望有4列x,y,foo_sum和bar_sum,这可能吗?

2 个答案:

答案 0 :(得分:1)

我认为这不可能,因为您的唯一x值的数量可能与唯一y值的数量不同。

例如,假设a是这样的:

+------+------+------+------+
| x    | y    | foo  | bar  |
+------+------+------+------+
|    1 |    1 |    3 |    4 |
|    1 |    2 |    3 |    6 |
|    1 |    1 |    3 |    6 |
|    1 |    2 |    8 |    3 |
|    2 |    1 |    7 |   32 |
|    2 |    2 |    7 |   34 |
|    2 |    3 |    8 |    3 |
+------+------+------+------+

第一个查询(foo_sum GROUP BY x)会给出:

+------+------+---------+
| x    | y    | foo_sum |
+------+------+---------+
|    1 |    1 |      17 |
|    2 |    1 |      22 |
+------+------+---------+

第二个(bar_sum GROUP BY y)给出:

+------+------+---------+
| x    | y    | bar_sum |
+------+------+---------+
|    1 |    1 |      42 |
|    1 |    2 |      43 |
|    2 |    3 |       3 |
+------+------+---------+

如何在bar_sum表的末尾混搭foo_sum列?对于(x,y)=(2,3),没有对应foo_sum值,但 对应bar_sum

你能达到的最好成绩是:

+------+------+---------+-------+
| x    | y    | bar_sum |foo_sum|
+------+------+---------+-------+
|    1 |    1 |      42 |    17 |
|    1 |    2 |      43 |  NULL |
|    2 |    3 |       3 |  NULL |
|    2 |    1 |    NULL |    22 |
+------+------+---------+-------+

要实现这一点,我能想到的唯一方法是使用FULL OUTER JOIN。请注意,执行SELECT x, y, SUM(foo), SUM(bar) FROM a GROUP BY x,y不会给出与其分组不同的结果。

SELECT t1.x,t1.y,foo_sum,bar_sum
FROM
(SELECT x, y, SUM(foo) as foo_sum
FROM A
GROUP BY x) t1
FULL OUTER JOIN
(SELECT x, y, SUM(bar) as bar_sum
FROM A
GROUP BY y) t2
ON t1.x=t2.x AND t1.y=t2.y

这可确保插入每个表中的所有x,y组合,即使其他表中没有对应的x,y

然而 MySQL没有FULL OUTER JOIN,您必须A FULL OUTER JOIN B UNION LEFTRIGHT来模拟SELECT ... FROM A LEFT JOIN B ON ... UNION SELECT ... FROM A RIGHT JOIN B ON ... 联合起来:

SELECT t1.x,t1.y,foo_sum,bar_sum
FROM
(SELECT x, y, SUM(foo) as foo_sum
FROM A
GROUP BY x) t1
LEFT JOIN                        -- need FULL OUTER JOIN
(SELECT x, y, SUM(bar) as bar_sum
FROM A
GROUP BY y) t2
ON t1.x=t2.x AND t1.y=t2.y

UNION

SELECT t2.x,t2.y,foo_sum,bar_sum
FROM
(SELECT x, y, SUM(foo) as foo_sum
FROM A
GROUP BY x) t1
RIGHT JOIN                        -- need FULL OUTER JOIN
(SELECT x, y, SUM(bar) as bar_sum
FROM A
GROUP BY y) t2
ON t1.x=t2.x AND t1.y=t2.y

在你的情况下,这转化为非常丑陋:

SUM

非常低效!我建议你在PHP方面(或者你使用MySQL的其他语言)进行分组,而不是SQL方面。

谁知道,可能有更有效的方法来做到这一点,因为你想要的只是{{1}} s - 可能有一种聪明的方法来分组和求和以实现你的效果。

答案 1 :(得分:0)

与...相同:

select a.x, a.y, sum(a.foo) as foo_sum, sum(a.bar) as bar_sum 
from a 
group by a.x ,a.y