RETORNAR ZERO QUANDO NÃO TIVER REGISTRO

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
djoq
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 54
Registrado em: Sex, 27 Jan 2012 8:16 am
Localização: Londres UK

Olá pessoal, estou com este impasse e preciso da ajuda de vocês.
É o seguinte: Tem como retornar zero, usando nvl, se a minha consulta não traz registro?

Este é o código:

Selecionar tudo

SELECT NVL(CLI.COD_CLI,0), NVL(SUM(VALOR),0) VL_VEN_CLI
FROM   HIST_FINANCEIRO HF, CLIENTES CLI
        WHERE    HF.CODCLI = CLI.COD_CLI
        AND    (((HF.COD_OCORR  = 510 OR
                  HF.COD_OCORR  = 509 OR
                  HF.COD_OCORR  = 707 OR
                  HF.COD_OCORR  = 717))
         OR
                (HF.COD_OCORR = 716))
GROUP BY CLI.COD_CLI
No meu caso está retornando os valores em branco. Mas preciso que retorne zero.

Qualquer ajudar é bem vinda. Obg.
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

O nvl só irá retornar o valor padrão quando o valor da coluna é null. Quando nenhum registro é retornado na consulta, não existem colunas para a função nvl ser aplicada.

Caso o cliente sempre exista na tabela clientes, seria melhor utilizar um outer join:

Selecionar tudo

with cli as ( select 1 cod_cli from dual )
   , hf  as ( select 2 codcli, 100 valor, 510 cod_ocorr from dual )
select cli.cod_cli, nvl( sum( hf.valor ), 0 )
from   clientes cli 
left outer join hf on ( hf.codcli = cli.cod_cli and ( hf.cod_ocorr in ( 509, 510, 707, 716, 717 ) ) )
group by cli.cod_cli
Caso haja a possibilidade de não existir nenhum cliente, acredito que seria melhor tratar em seu código mesmo.
djoq
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 54
Registrado em: Sex, 27 Jan 2012 8:16 am
Localização: Londres UK

Obrigada pela ajuda Rogenaro. E no caso da meu select ser beem maior.
Tipo :

Selecionar tudo

select....NVL(FIL.COD_SAT, NULL), NVL(FIL.COD_FPAS, NULL),
       NVL(SUM(DECODE(HF.COD_OCORR,6,0,23,0,VALOR)),0) VL_SALARIO_CONTRIBUICAO,
       NVL(NVL(SUM(DECODE(IFE.COD_ESPECIFICACAO,1,DECODE(HF.COD_OCORR,6,0,23,0,VALOR),0)),0) +
       NVL(SUM(DECODE(IFE.COD_ESPECIFICACAO,5,DECODE(HF.COD_OCORR,6,0,23,0,VALOR),0)),0),0) VL_SALARIO_CONTRIBUICAO1,
       NVL(SUM(DECODE(IFE.COD_ESPECIFICACAO,2,DECODE(HF.COD_OCORR,6,0,23,0,VALOR),0)),0) VL_SALARIO_CONTRIBUICAO2,
       NVL(SUM(DECODE(IFE.COD_ESPECIFICACAO,3,DECODE(HF.COD_OCORR,6,0,23,0,VALOR),0)),0) VL_SALARIO_CONTRIBUICAO3,
       NVL(SUM(DECODE(IFE.COD_ESPECIFICACAO,4,DECODE(HF.COD_OCORR,6,0,23,0,VALOR),0)),0) VL_SALARIO_CONTRIBUICAO4,
       NVL(SUM (DECODE(HF.COD_OCORR,6,VALOR,23,VALOR,0)),0) VL_PRO_LABORE,
       NVL(COUNT(DISTINCT(HF.MATRICULA)),0) T_F,
       --FIL.NOME_FILIAL NOME, FIL.COD_FILIAL,
       NVL(DECODE(FIL.GR_INCRA,'S',TRUNC(FIL.PERC_INCRA,2),0),0) PERC_INCRA,
       NVL(DECODE(FIL.GR_SEBRAE,'S',TRUNC(FIL.PERC_SEBRAE,2),0),0) PERC_SEBRAE,
       NVL(DECODE(FIL.GR_SENAI,'S',TRUNC(FIL.PERC_SENAI,2),0),0) PERC_SENAI,
       NVL(DECODE(FIL.GR_SESI,'S',TRUNC(FIL.PERC_SESI,2),0),0) PERC_SESI,....
from....where....

É uma query para um Report. Tem algo mais simples. Obrigadinha =)
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Fica um pouco mais chato, mas é possível sim:

Selecionar tudo

select a.* 
from
(
  select a.*
       , min( prioridade ) over () min_prioridade
  from
  ( select /* seus campos de retorno aqui */
         , 1 prioridade -- adicione esta coluna no final
    from   /* tabelas, joins e condições where da sua consulta */
    union all
    select 0 coluna1
         , 0 coluna2
         , ... /* uma coluna para cada campo */
         , 2 prioridade
    from   dual
  ) a
) a
/* caso existam registros retornados pela primeira consulta
   (sua consulta inicial), retorna somente estes registros
   caso retornar somente o registro com as colunas zeradas,
   retorna este registro
*/
where  ( a.prioridade = a.min_prioridade )
djoq
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 54
Registrado em: Sex, 27 Jan 2012 8:16 am
Localização: Londres UK

Vou tentar.
Obrigada pela ajuda.
leticiafelixmoraes
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Ter, 26 Jul 2022 11:32 am
Localização: Brasil

rogenaro escreveu:
Qui, 03 Jan 2013 7:13 am
Fica um pouco mais chato, mas é possível sim:

Selecionar tudo

select a.* 
from
(
  select a.*
       , min( prioridade ) over () min_prioridade
  from
  ( select /* seus campos de retorno aqui */
         , 1 prioridade -- adicione esta coluna no final
    from   /* tabelas, joins e condições where da sua consulta */
    union all
    select 0 coluna1
         , 0 coluna2
         , ... /* uma coluna para cada campo */
         , 2 prioridade
    from   dual
  ) a
) a
/* caso existam registros retornados pela primeira consulta
   (sua consulta inicial), retorna somente estes registros
   caso retornar somente o registro com as colunas zeradas,
   retorna este registro
*/
where  ( a.prioridade = a.min_prioridade )
Também estava precisando de auxílio nessa questão, e deu super certo! Muitíssimo obrigada!
Responder
  • Informação