在 Oracle 中按 substr 分组

Group by substr in 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;

我想要实现的是 return 每个帐号的 CRE1 和 CRE2 费用类型金额的总和,其中该总和不为 0。

如果分组依据中没有 substr,查询将运行并且 returns 预期结果 除了 CRE1 和 CRE2 费用类型未汇总在一行中.

当我在 group by 中添加 substr 时,出现以下错误消息:

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

有没有办法在 Oracle 中实现这一点?

编辑: 对于可能遇到此问题的任何人 post。解决方法如下:

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;

我相信你想要这样的东西:

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;

我随意使用了您的列别名。这里最大的 take-away 是 sum() 不属于您的分组依据,因为我们将该列与公式聚合在一起,但是您的 CASE 语句的别名确实属于您的分组依据,因为它不是通过公式汇总。

聚合函数不属于 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;