Как использовать запрос на объединение для одной и той же таблицы и другой группы в MySQL? - PullRequest
1 голос
/ 28 февраля 2012

У меня есть 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 ]

1 голос
/ 28 февраля 2012

Я не думаю, что это возможно, поскольку число уникальных значений 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?Существует нет соответствующего foo_sum значения для (x, y) = (2,3), но есть соответствующего 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 с объединением LEFT и RIGHT:

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

Это крайне неэффективно !Вместо этого я предлагаю выполнить группировку на стороне PHP (или на любом другом языке, который вы используете с MySQL), а не на стороне SQL.

Кто знает, может быть более эффективный способ сделать это, так как все, что вы хотитеis SUM s - может быть разумный способ группировки и суммирования для достижения вашего эффекта.

0 голосов
/ 28 февраля 2012

Это так же, как:

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