首页 > 解决方案 > ORA-00979: 不是 GROUP BY 表达式 - 在选择中调用函数

问题描述

在 SELECT 中调用两个函数时出现问题。在主 Select 中,调用函数“getCodGama”和“getDescGama”。当我尝试运行它时,显示下一个错误“ORA-00979:不是 GROUP BY 表达式”。如果我将这两个别名(codGama 和 descGama)放在 Group By 上,我会遇到同样的错误。我不知道我能做什么,因为,如果我在 group by 中放置或不放置函数的这两个别名,我会遇到同样的错误。函数“getCodGama”返回一个 VARCHAR2。函数“getDescGama”返回一个 VARCHAR2。

SELECT productos.prod_nmu                nmuproducto,
                marcas.marc_codmarca              codmarca,
                familias.fami_codfamilia          codfamilia,
                depositosfisicos.depf_coddeposito coddeposito,
                stock.stck_codstock               codstock,
                inventariopartidas.part_codpart   codpart,
                /*GAMA*/
                TO_CHAR(negozi.pkg_inv_mdw_servicios_ne.getCodGama(productos.fami_idfamilia)) codGama,
                TO_CHAR(negozi.pkg_inv_mdw_servicios_ne.getDescGama(productos.fami_idfamilia)) descGama,
                --
                SUM (exist.cantidadexist)         cantidadexist ,
                SUM (exist.cantidadexist - nvl(reservas.cantidadres,0) ) cantidaddisp

         FROM   n2_inv_expr_existencia_produc  existenciaproduc,
                n2_inv_prod_productos          productos,
                n2_inv_depf_deposito_fisico    depositosfisicos,
                n2_inv_estl_estructura_logica  estructlogica,
                n2_inv_depl_deposito_logico    deplogico,
                n2_inv_gcom_grupos_comerciales gruposcomerciales,
                n2_inv_fami_familias           familias,
                n2_inv_stck_stocks             stock,
                n2_inv_rstp_rela_stock_partida relastockpartida,
                n2_inv_part_partidas           inventariopartidas,
                n2_inv_tdep_tipo_deposito      tipodedeposito,
                N2_INV_MARC_MARCAS             marcas,
                /*Gama*/
                --n2_ate_para_parametros para,-- retorna descripcion de gama en cursor
                --n2_cco_sgfa_subgamas_familias sgfa,
                --n2_ate_sgam_subgamas sgam,
                --
                /* Existencias */
    ( SELECT existenciaproduc.expr_idexistencia, relastockpartida.rstp_idrelstpart,-- sgfa.fami_idfamilia, sgam.sgam_gama_id,
                     COUNT(distinct existenciaserial.exsr_esn_pin ) cantidadexist
         FROM   n2_inv_expr_existencia_produc existenciaproduc,
                n2_inv_exsr_existencias_serial existenciaserial,
                n2_inv_prod_productos         productos,
                n2_inv_depf_deposito_fisico   depositosfisicos,
                n2_inv_estl_estructura_logica estructlogica,
                n2_inv_depl_deposito_logico   deplogico,
                n2_inv_gcom_grupos_comerciales gruposcomerciales,
                n2_inv_fami_familias          familias,
                n2_inv_stck_stocks            stock,
                n2_inv_rstp_rela_stock_partida relastockpartida,
                n2_inv_part_partidas          inventariopartidas,
                n2_inv_tdep_tipo_deposito     tipodedeposito,
                N2_INV_MARC_MARCAS            marcas,
                /*Gama*/
                n2_ate_para_parametros para,
                n2_cco_sgfa_subgamas_familias sgfa,
                n2_ate_sgam_subgamas sgam
          WHERE productos.prod_idproducto       = existenciaproduc.prod_idproducto
          AND   existenciaserial.expr_idexistencia =existenciaproduc.expr_idexistencia
          AND   depositosfisicos.depf_iddeposito= existenciaproduc.depf_iddeposito
          AND   depositosfisicos.tdep_idtipo    = tipodedeposito.tdep_idtipo
          AND   existenciaproduc.estl_idestruct_logica = estructlogica.estl_idestruct_logica
          AND   estructlogica.rstp_idrelstpart  = relastockpartida.rstp_idrelstpart
          AND   stock.stck_idstock              = relastockpartida.stck_idstock
          AND   inventariopartidas.part_idpartida = relastockpartida.part_idpartida
          AND   depositosfisicos.tdep_idtipo    = estructlogica.tdep_idtipo
          AND   estructlogica.depl_idlogico     = deplogico.depl_idlogico
          AND   productos.gcom_idgrupocom       = gruposcomerciales.gcom_idgrupocom
          AND   productos.marc_idmarca          = marcas.marc_idmarca
         -- AND   gruposcomerciales.gcom_producto_servicio = ctegrpPortable
          AND   productos.fami_idfamilia        = familias.fami_idfamilia(+)
          /*Gama*/
          AND  para.para_valor2 = sgam.sgam_gama_id
          AND  para.para_atributo = 'GAMAS TERMINALES'
          AND  sgfa.sgfa_fecha_baja IS NULL
          AND  sgam.sgam_activo = 'S'
          AND  sgfa.sgam_idsubgama = sgam.sgam_idsubgama
          AND  sgfa.fami_idfamilia = productos.fami_idfamilia
          --
          AND   depositosfisicos.depf_iddeposito= 688--idep
          AND   stock.stck_disponible           = 'S'
          --AND  ( productos.prod_idproducto      = idproducto   OR idproducto = -1 )
          AND  ( stock.stck_codstock            = nvl(NULL,   stock.stck_codstock)  )--nvl(codStock,   stock.stck_codstock)  )
          AND  ( marcas.marc_codmarca           = nvl(NULL,   marcas.marc_codmarca )  )--nvl(codMarca,   marcas.marc_codmarca )  )
          AND  ( familias.fami_codfamilia       = nvl(NULL, familias.fami_codfamilia))--nvl(codFamilia, familias.fami_codfamilia))
          AND  (para.para_valor2                = nvl(NULL, para.para_valor2))--nvl(pcodGama, para.para_valor2))
          GROUP BY existenciaproduc.expr_idexistencia, relastockpartida.rstp_idrelstpart)--, sgfa.fami_idfamilia, sgam.sgam_gama_id)
          exist,
            /* Reservas */
        (SELECT   expr_idexistencia, RSTP_IDRELSTPART, SUM (repm_cant_reservada) cantidadres
         FROM     n2_inv_repm_reservaprod_mdw
         GROUP BY expr_idexistencia, RSTP_IDRELSTPART) reservas

          WHERE productos.prod_idproducto       = existenciaproduc.prod_idproducto
          AND   depositosfisicos.depf_iddeposito= existenciaproduc.depf_iddeposito
          AND   depositosfisicos.tdep_idtipo    = tipodedeposito.tdep_idtipo
          AND   existenciaproduc.estl_idestruct_logica = estructlogica.estl_idestruct_logica
          AND   estructlogica.rstp_idrelstpart = relastockpartida.rstp_idrelstpart
          AND   stock.stck_idstock             = relastockpartida.stck_idstock
          AND   inventariopartidas.part_idpartida = relastockpartida.part_idpartida
          AND   depositosfisicos.tdep_idtipo   = estructlogica.tdep_idtipo
          AND   estructlogica.depl_idlogico    = deplogico.depl_idlogico
          AND   productos.gcom_idgrupocom      = gruposcomerciales.gcom_idgrupocom
          AND   productos.marc_idmarca         = marcas.marc_idmarca
          -- Contabilizamos existencias
          AND   existenciaproduc.expr_idexistencia = exist.expr_idexistencia
          AND   relastockpartida.rstp_idrelstpart =  exist.rstp_idrelstpart
          /*Gama*/
          --AND   productos.fami_idfamilia = exist.fami_idfamilia
          --AND   para.para_valor2         = exist.sgam_gama_id
          --AND   para.para_atributo       = 'GAMAS TERMINALES'
          -- Contabilizo reservas
          AND   exist.expr_idexistencia = reservas.expr_idexistencia(+)
          AND   exist.rstp_idrelstpart  = reservas.RSTP_IDRELSTPART(+)
          AND   productos.fami_idfamilia= familias.fami_idfamilia(+)
          --AND  sgfa.sgfa_fecha_baja IS NULL
          --AND  sgam.sgam_activo = 'S'
          --AND  sgfa.sgam_idsubgama = sgam.sgam_idsubgama

          --AND  (pcodGama IS NULL OR para.para_valor2 = pcodGama)
          --
          GROUP BY productos.prod_nmu,
                   marcas.marc_codmarca,
                   familias.fami_codfamilia,
                   depositosfisicos.depf_coddeposito,
                   stock.stck_codstock,
                   inventariopartidas.part_codpart;

标签: oracleplsqlgroup-by

解决方案


一个更简单的例子可能会使问题更清楚。如果您的查询是这样的:

select max(upper(dummy)) as demo
from   dual d
group by d.demo;

ORA-00904: "D"."DEMO": invalid identifier

那么它需要是这样的:

select max(upper(dummy)) as demo
from   dual d
group by upper(dummy);

从性能的角度来看,确保您的用户定义函数被定义为确定性的(假设它们实际上是,我猜它们必须是,否则它们在 SQL 查询中不会有太多用处)以确保它们被调用的次数很少尽可能多的时间,并且如果您想在并行查询中使用它们,则可以很好地并行启用。


推荐阅读