Группировать по substr в Oracle

Ниже приведен пример запроса:

select acct_no, month, sum(amount), substr(charge_type, 1, 3),
       case when (charge_type in ('CRE1', 'CRE2')
            then 'electronic payment'
            else 'cash'
       end as 'payment_type'
from   billing_data
where  charge_type in ('CRE1', 'CRE2', 'CASH')
group  by acct_no, month, sum(amount), 
          substr(charge_type, 1, 3)
having sum(amount) != 0
order  by acct_no asc;

Чего я пытаюсь добиться, так это вернуть сумму сумм типов начислений CRE1 и CRE2, сгруппированных вместе для каждого номера счета, где эта сумма не равна 0.

Без substr в группе by запрос выполняется и возвращает ожидаемые результаты, за исключением типов начислений CRE1 и CRE2, которые не суммируются вместе в одной строке.

Когда я добавляю substr в группу, я получаю следующее сообщение об ошибке:

[Error] Execution (63: 15): ORA-00979: not a GROUP BY expression

Есть ли способ добиться этого в Oracle?

Изменить: для всех, кто может увидеть это сообщение. Решение выглядит следующим образом:

select acct_no, month, sum(amount) as sumofamount, 
       substr(charge_type, 1, 3) as charge_type_substring,
       (
       case when (charge_type in ('CRE1', 'CRE2')
            then 'electronic payment'
            else 'cash'
       end) as payment_type
from   billing_data
where  charge_type in ('CRE1', 'CRE2', 'CASH')
group  by acct_no, month, substr(charge_type, 1, 3), 
       (
       case when (charge_type in ('CRE1', 'CRE2')
            then 'electronic payment'
            else 'cash'
       end)
       having sum(amount) != 0
order  by acct_no asc;

person ComputersAreNeat    schedule 20.02.2018    source источник
comment
Проблема в том, что вы пытаетесь сгруппировать по совокупности: sum(amount). Вы хотите суммировать сумму или сгруппировать по ней? Кроме того, вы не группируете по полю payment_type и не агрегируете его по формуле. Он должен войти в вашу группу GROUP BY.   -  person JNevill    schedule 21.02.2018
comment
Спасибо за ваш отзыв. Я пытаюсь суммировать сумму обоих типов заряда CRE1 и CRE2 и отображать сумму в одной строке.   -  person ComputersAreNeat    schedule 21.02.2018
comment
Кроме того, вам нужно будет включить case when (charge_type in ('CRE1', 'CRE2') then 'electronic payment' else 'cash' в предложение group by. (Или сгруппируйте по charge_type, но я не думаю, что это то, что вам нужно.   -  person Shannon Severance    schedule 21.02.2018


Ответы (2)


Я считаю, что вы собираетесь что-то вроде этого:

select acct_no, month, sum(amount) as sumofamount, substr(charge_type, 1, 3) as charge_type_substring,
       case when (charge_type in ('CRE1', 'CRE2')
            then 'electronic payment'
            else 'cash'
       end as 'payment_type'
from   billing_data
where  charge_type in ('CRE1', 'CRE2', 'CASH')
group  by acct_no, month, charge_type_substring, payment_type
having sum(amount) != 0
order  by acct_no asc;

Я позволил себе некоторые вольности с вашими псевдонимами столбцов. Главный вывод здесь заключается в том, что sum() не принадлежит вашей группе, поскольку мы агрегируем этот столбец с помощью формулы, но псевдоним для вашего оператора CASE ДЕЙСТВИТЕЛЬНО принадлежит вашей группе, поскольку он не агрегируется по формуле.

person JNevill    schedule 20.02.2018
comment
Спасибо! Это помогает! Однако я узнаю, что вы не можете использовать псевдонимы в предложении group-by. - person ComputersAreNeat; 21.02.2018
comment
Думаю, я понял это. Я добавил весь оператор case за вычетом псевдонима в группу в скобках, и это работает! Я отредактирую исходный пост с окончательным результатом. Спасибо еще раз! - person ComputersAreNeat; 21.02.2018

Функции агрегации не относятся к GROUP BY.

Вы можете решить свою проблему, взглянув только на первые три буквы charge_type:

select acct_no, month, sum(amount), substr(charge_type, 1, 3),
       (case when substr(charge_type, 1, 3) = 'CRE'
             then 'electronic payment'
             else 'cash'
        end) as payment_type
from  billing_data
where charge_type in ('CRE1', 'CRE2', 'CASH')
group by acct_no, month, substr(charge_type, 1, 3)
having sum(amount) <> 0
order by acct_no asc;
person Gordon Linoff    schedule 20.02.2018