2015-06-28 1 views
0

Я пытаюсь получить каждую из следующих сумм в виде полей, я получаю только внешний, другие два возвращают неопределенный индекс.MySQL умножает функции SUM() внутри одного запроса как поля

Как поместить их в качестве полей?

SELECT 
(SELECT SUM(amount) AS income 
    FROM transaction 
    WHERE 
    type = '1' && state = 'a') 

- (SELECT SUM(amount) AS expense 
    FROM transaction 
    WHERE 
    type = '2' && state = 'a') 
    AS balance 

Баланс работает, но для доходов и расходов я получаю неопределенный индекс.

ответ

1

Использование условной агрегации:

SELECT SUM(CASE WHEN type = '1' AND state = 'a' THEN amount ELSE 0 
      END) as income, 
     SUM(CASE WHEN type = '2' AND state = 'a' THEN amount ELSE 0 
      END) as balance 
FROM transaction; 

Если вы все еще хотите разницу, то вам нужно повторить логику:

SELECT SUM(CASE WHEN type = '1' AND state = 'a' THEN amount ELSE 0 
      END) as income, 
     SUM(CASE WHEN type = '2' AND state = 'a' THEN amount ELSE 0 
      END) as expense, 
     (SUM(CASE WHEN type = '1' AND state = 'a' THEN amount ELSE 0 END) - 
     SUM(CASE WHEN type = '2' AND state = 'a' THEN amount ELSE 0 END) 
     ) as balance 
FROM transaction; 

EDIT:

На самом деле, это лучше вынесем общие условия в пункте WHERE:

SELECT SUM(CASE WHEN type = '1' THEN amount ELSE 0 END) as income, 
     SUM(CASE WHEN type = '2' THEN amount ELSE 0 END) as expense, 
     (SUM(CASE WHEN type = '1' THEN amount ELSE 0 END) - 
     SUM(CASE WHEN type = '2' THEN amount ELSE 0 END) 
     ) as balance 
FROM transaction 
WHERE state = 'a' AND type IN ('1', '2'); 

Это может воспользоваться индексом на transaction(state, type, amount).

+0

Вы были быстры в этом, спасибо. – Relm

1

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

select sum(case when `type` = '1' then `amount` else 0 end) as `income` 
    , sum(case when `type` = '2' then `amount` else 0 end) as `expense ` 
    , sum((case when `type` = '2' then -1 else 1 end) * `amount`) as `difference` 
from `transaction` 
where `type` in ('1', '2') 
where `state` = 'a' 
+0

Почему вы удалите это заявление где вы говорили, что я не должен использовать «&&», я хотел спросить, почему. – Relm

+0

@ Relm: Потому что я ошибся - я думаю, только MySQL допускает такой синтаксис. – potashin

+0

Oohhh ok, cool. – Relm

1

Вы не можете получить доступ к income и expense, поскольку они определены только в их соответствующих подзапросах, а не в запросе верхнего уровня, в котором есть только одно поле - разница между ними. Я бы вложил в подзапрос, а затем выделил их оба и разницу между ними. Для того, чтобы сделать этот запрос проще и устранить необходимость подзапросов, вы можете эмулировать поведение двух различных where положений, извлекая различные условия для case выражений в аргументах sum «s:

SELECT income, expense, income - expense AS balance 
FROM (SELECT SUM(CASE type WHEN 1 THEN amount ELSE NULL) AS income, 
       SUM(CASE type WHEN 2 THEN amount ELSE NULL) AS expense, 
     FROM `transaction` 
     WHERE state = 'a') t 
+0

t? Что такое «т» и где используется? – Relm

+1

@Relm 't' - псевдоним таблицы для подзапроса. Он не используется напрямую, но MySQL (и несколько других реляционных баз данных) имеет мандат. Без него вы получите сообщение об ошибке «ERROR 1248 (42000): каждая производная таблица должна иметь свой собственный псевдоним». – Mureinik

Смежные вопросы