Oracle含聚合函数查询分组报错及ItemCode重复问题咨询
问题原因分析
- 最初报错
not a group by function,是因为SELECT子句中使用的D.unitpricef既没有放入GROUP BY子句,也没有被聚合函数包裹,不符合Oracle分组查询的语法规则。 - 将
D.unitpricef加入GROUP BY后同一个ItemCode出现多行,是因为GROUP BY的分组规则是所有指定字段值完全一致的行才会被合并为一行:同一个ItemCode如果对应多个不同的D.unitpricef值、或者不同的H.InvoType值,就会被拆分为多个分组返回。 - 原SQL中GROUP BY包含
H.InvoType也是同个ItemCode返回多行的核心原因之一:如果同一个ItemCode关联的发票存在InvoType=1和InvoType≠1的记录,会被分为两个独立分组。
解决方案
需求为每个ItemCode仅展示一行,需调整分组逻辑和字段聚合规则,以下为两种常见业务场景的实现方案:
场景1:金额统计逻辑为「单条明细金额累加」(绝大多数进销存场景的通用规则)
单条明细金额为数量*单价,汇总金额为所有明细金额的和,无需将单价加入GROUP BY,同时调整EquName的判断逻辑用聚合函数包裹,避免将H.InvoType加入GROUP BY:
SELECT ItemCode, CASE WHEN MAX(H.InvoType) = 1 THEN concat(ItemCode,' ( SLT Equipment )' ) ELSE concat(ItemCode,' ( CONBES Equipment )' ) END as EquName, CASE WHEN TRIM(SUM(QTY)) is null THEN '' ELSE TRIM(TO_CHAR(SUM(QTY),'999999')) END as QTY, CAST(SUM(QTY * D.unitpricef) AS NUMBER(38,2)) AS Amount FROM Invoicedetails D INNER JOIN invoiceheader H ON D.InvoiceNo = H.InvoiceNo INNER JOIN Equipment E ON E.EquCode = ItemCode WHERE H.CancelStat= 0 AND H.ReceiptStat = 1 AND H.BCCODE = 'xxx' GROUP BY ItemCode ORDER BY ItemCode ASC;
场景2:金额统计逻辑为「总数量*统一单价」
如果业务要求必须先统计总数量,再乘以该ItemCode的固定单价,可通过聚合函数取统一单价(比如平均单价、最新单价、最高单价),示例写法如下:
-- 以取平均单价为例,可根据业务需要替换为MAX(D.unitpricef)、MIN(D.unitpricef)等 CAST( (SUM(QTY) * AVG(D.unitpricef)) AS NUMBER(38,2)) AS Amount
内容的提问来源于stack exchange,提问作者Sameera Udakumbura
相关产品推荐
相关产品推荐

