如何添加解码但也有计数、分组依据和排序依据 - 而不是分组依据表达式

How to add decode but also have count, group by and order by - not a group by expression

我对 Oracle 比较陌生。我正在尝试计算 vendor/model 的端口数。但是,我只想要 port_addr_status 为 3 或 4 的。出于某种原因,我收到错误

ORA-00979 not a group by expression

这就是我目前所拥有的。它在没有解码部分的情况下工作,但我认为 ('3','4') 中带有 pi.port_addr.status 的部分在没有解码部分的情况下无法工作。我也愿意解决这个问题。

select 
   count(pi.port) as cnt, d.VENDOR, trim(d.model) as model, 
   decode(pi.PORT_ADDR_STATUS, '1', 'Unassigned', '2','Pending','3','In Service', 
                               '4','Pending Disco', '5','Trouble', '6','Reserved', 
                               '7','Reserved Capacity', pi.PORT_ADDR_STATUS)
from
   table1 pi,
   table2 d,
   table3 c
where
   pi.id = d.id and
   pi.circuit_id = c.circuit_id 
   and pi.port_addr_status in ('3','4')
   and (d.dslam_type_desc not in ('AGGREGATOR') or d.dslam_type_desc is null)
   and d.DSLAM not like '%@%' 
group by 
       d.VENDOR, d.model --, trim(d.model), pi.RACK, pi.SHELF, pi.SLOT, pi.PORT, pi.BROADBAND_CIRCUIT_ID, d.DSLAM, 
order by
       d.VENDOR asc, cnt desc

这是示例输出:

1031    Adtran  TA5000
10      Adtran  TA1248V
3       Adtran  TA1248

您可以在 select 列表中使用 decode 语句和聚合函数,最好是 max as

max( decode(pi.PORT_ADDR_STATUS, '1', 'Unassigned', '2','Pending', .... )

您收到该错误的原因是:

  1. 使用 GROUP BY 子句时,您要求 DBMS 为您提供与 GROUP BY 列表相对应的一行
  2. 在您的情况下,您要求每个(供应商、型号)组合一行
  3. 因为这些行中的每一行都可能代表许多 "underlying" 行(例如,供应商=A 和模型=B 的 5 行),您可以在 select 列表中拥有的唯一其他字段必须是聚合(这就是 "count" 字段起作用的原因,它计算行数,即它可以采用许多行值和 return 单个值)
  4. DECODE 函数不是聚合函数 - 它不能 "collapse" 将多个值合并为一个值(例如,MAX() 可以)

在我看来,你的 DECODE 函数好像是 return 的字符串,所以我建议你使用 LISTAGG 函数聚合字符串(因此,如果你的 5 行的值为 'asdf',[= 33=、'qwer'、'rewq' 和 'zxcv' LISTAGG 函数将 return 单个字符串:'asdf,fdsa,qwer,rewq,zxcv')

因此,您可以将 DECODE(...) 调用替换为,例如LISTAGG(解码(...), ',')

LISTAGG 函数参考:https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions089.htm#SQLRF30030

由于输出中不需要解码的端口类型,只需将其从 select 列表中删除即可。 Group By 应包括 select 列表中的所有内容,但聚合函数除外。下面的查询应该可以完成这项工作:

select 
   count(pi.port) as cnt, d.VENDOR, trim(d.model) as model
from
   table1 pi,
   table2 d,
   table3 c
where
   pi.id = d.id and
   pi.circuit_id = c.circuit_id 
   and pi.port_addr_status in ('3','4')
   and (d.dslam_type_desc not in ('AGGREGATOR') or d.dslam_type_desc is null)
   and d.DSLAM not like '%@%' 
group by 
       d.VENDOR, trim(d.model)
order by
       d.VENDOR asc, cnt desc

请注意,这里实现了对特定端口类型的过滤:

and pi.port_addr_status in ('3','4')

在 where 子句中 - 原始查询中的 decode 语句没有解决您的要求,而是导致错误的直接原因。在像这样的基本聚合查询中,group by 应该包含 select 列表中不是聚合函数的每个项目。