MySQL SubQueries для нескольких сумм - PullRequest
0 голосов
/ 12 февраля 2011

Если мне нужно получить пять + разных значений SUM со схожими условиями WHERE, лучший (возможно, единственный) способ сделать это с помощью одного запроса с пятью подзапросами?Например, мой запрос:

SELECT user, 
(SELECT SUM(amount) FROM table t, table2 t2 WHERE t.table2_id = t2.id AND table2.type = 1 AND user = 1 AND date = x) AS one,
(SELECT SUM(amount) FROM table t, table2 t2 WHERE t.table2_id = t2.id AND table2.type = 2 AND user = 1 AND date = x) AS two, 
(SELECT SUM(amount) FROM table t, table2 t2 WHERE t.table2_id = t2.id AND table2.type = 3 AND user = 1 AND date = x) AS three, 
(SELECT SUM(amount) FROM table t, table2 t2 WHERE t.table2_id = t2.id AND table2.type = 4 AND user = 1 AND date = x) AS four, 
(SELECT SUM(amount) FROM table t, table2 t2 WHERE t.table2_id = t2.id AND table2.type = 5 AND user = 1 AND date = x) AS five 
FROM table 
WHERE user = 1

Пока мои запросы были очень быстрыми, но я беспокоюсь о значении пяти + подзапросов, когда есть еще много записей.

Ииз любопытства, один такой запрос с пятью подзапросами имеет преимущество в производительности / недостаток по сравнению с пятью отдельными запросами?Я предполагал, что это быстрее, потому что это только одна поездка в базу данных против 5?

РЕДАКТИРОВАТЬ: есть таблица 2 из примерно 60 записей, которые используются для классификации тысяч записей в таблице 1. Каждая запись в таблице2 классифицируется по значению типа 1 - 5 (это то, что я использую для группировки элементов, для которых требуется сумма).

Ответы [ 3 ]

1 голос
/ 12 февраля 2011

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

select user, type, sum(amount)
where user = 1
and date = x
and type between (1,5)
group by user, type

это даст вам

1,1,sum
1,2,sum
1,3,sum
1,4,sum
1,5,sum

вместо

1,sum1,sum2,sum3,sum4,sum5

Это должно быть достаточно для того, что вам нужно, я подозреваю, без всяких хлопот.

1 голос
/ 13 февраля 2011
  1. Использовать ANSI JOINS
  2. Вам лучше написать запрос в форме PIVOT, как запрос ниже

Переписано:

SELECT t.user, 
SUM(CASE table2.type WHEN 1 then amount else 0 end) As one,
SUM(CASE table2.type WHEN 2 then amount else 0 end) As two,
SUM(CASE table2.type WHEN 3 then amount else 0 end) As three,
SUM(CASE table2.type WHEN 4 then amount else 0 end) As four,
SUM(CASE table2.type WHEN 5 then amount else 0 end) As five
FROM table t
INNER JOIN table2 t2 ON t.table2_id = t2.id 
WHERE t.user = 1
  AND table2.type in (1,2,3,4,5)

Я понимаю, что ваш запрос псевдо, но в нем есть зависание WHERE user без предложения FROM.Что касается производительности, вышеизложенное проходит через таблицу за один проход.Форма подзапроса 5x заняла бы 5 проходов, но не должна быть значительно медленнее, если доступны надлежащие индексы.

1 голос
/ 12 февраля 2011

Вам нужен только один запрос, чтобы получить сумму для каждого типа:

SELECT 
  t2.type, 
  SUM(t.amount) 
FROM 
  table t 
INNER JOIN 
  table2 t2 
ON 
  t.table2_id = t2.id 
AND 
  t.user = 1
AND 
  t.date = x 
GROUP BY 
  t2.type
...