Oracle - invalid number of arguments com NVL + UNION ALL

01/03/2019

7

Boa noite a todos.

Possuo um relatório que usa o nvl para buscar um total de valor produzido por um determinado grupo (requisitantes) dividido pela quantidade de vezes que determinados serviços foram executados.
Atualmente a estrutura é basicamente assim:

select t.nomemedico, t.qtdereq, t.valoreq, t.qtdeconsulta, t.totalconsulta, round(t.valoreq / nullif(t.qtdeconsulta,0),2) resultado from (
select a.nm_guerra nomemedico,
COALESCE( (select sum(ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)),0) qtdereq,
COALESCE ( ( select sum( ab.vl_procedimento ) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)),0) valoreq,
COALESCE ( ( select sum (ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146)),0) qtdeconsulta,
COALESCE ( ( select sum (ab.vl_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146)),0) totalconsulta
from medico a where a.ie_vinculo_medico='1' and a.ie_corpo_clinico='S' and a.cd_pessoa_fisica <> '230' order by a.nm_guerra) t

Porém, no "valoreq", gostaria de adicionar a soma de dados de outras tabelas, então tentei da seguinte forma:

select t.nomemedico, t.qtdereq, t.valoreq, t.qtdeconsulta, t.totalconsulta, round(t.valoreq / nullif(t.qtdeconsulta,0),2) resultado, t.qtdetaxa, t.valortaxa from (
select a.nm_guerra nomemedico,
nvl( (select sum(ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)),0) qtdereq,
NVL( (select sum(valoreq) from ( select sum( ab.vl_procedimento ) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325))) valoreq
UNION all
select sum (valoreq) from (select sum(bc.vl_material)as "valoreq" from material_atend_paciente bc where trunc(bc.dt_atendimento) between :dtinicial and :dtfinal ) and bc.nr_atendimento=ab.nr_atendimento
, nvl ( ( select sum (ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146))) qtdeconsulta,
nvl ( ( select sum (ab.vl_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146)),0) totalconsulta,
from medico a where a.ie_vinculo_medico='1' and a.ie_corpo_clinico='S' and a.cd_pessoa_fisica <> '230' order by a.nm_guerra) t

Porém recebo a mensagem: ORA-00909: invalid number of arguments
00909. 00000 - "invalid number of arguments"
Error at Line: 5 Column: 1, bem onde está o UNION ALL
Individualmente consigo executar esses dois selects tranquilamente com o UNION ALL, mas dentro do NVL não estou conseguindo.

Se eu tentar )),0) valoreq na linha que antecede o UNION ALL recebo o ORA-00903: invalid table name
00903. 00000 - "invalid table name"

Alguém teria alguma sugestão para conseguir encaixar essa soma do valorreq com o UNION ALL ao mesmo tempo que utilizo o NVL?
Ou alguma alternativa? Até onde sei, COALESCE não tem suporte ao UNION ALL...

Obrigado!
Responder

Posts

Diego bom dia,

Os dois selects que vc está "unindo" devem ter exatamente as mesmas colunas. E você uni o resultado de dois "selects" e não colunas de um com colunas do outro.
Não etendi o segundo select da clausula uniom, mas vou tentar montar um exemplo com o código que vc postou... mas sugiro que teste individualmente o select anterior e posterior ao uniom, deixe os dois com as mesmas colunas depois acrescente a clausula uniom e por fim o select mais externo.... sugiro deixar o order by para clausula mais externa do seu código.


o resultado que vc vai ter será algo do tipo

nomemedico qtdereq, valorreq, qtdeconsulta, valorconsulta
dr um 0 0,00 1 1,00
dr um 1 1,00 0 0,00

Aí vc coloca um group by t.nomemedico soma suas méticas, e vai obter o que suponho que precisa...


qq duvida posta o código de novo...

por exemplo:
select t.nomemedico, sum(qtdereq), sum(valorreq), sum(qtdeconsulta), sum(valorconsulta) from (
-- 1o select
select a.nm_guerra nomemedico,
nvl( (select sum(ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, ''dd'') between :dt_inicial and :dt_final and ab.cd_motivo_exc_conta is null and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)),0) qtdereq,
NVL( (select sum(valoreq) from ( select sum( ab.vl_procedimento ) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, ''dd'') between :dt_inicial and :dt_final and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325))) valoreq,
0 qtdeconsuta,
0 totalconsulta
from medico a where a.ie_vinculo_medico=''1'' and a.ie_corpo_clinico=''S'' and a.cd_pessoa_fisica <> ''230''

UNION ALL

-- 2o select
select a.nm_guerra nomemedico,
0 qtdereq,
sum (valoreq) from (select sum(bc.vl_material)as "valoreq" -- NAO ENTENDI O QUE VC FEZ AQUI
from material_atend_paciente bc where trunc(bc.dt_atendimento) between :dtinicial and :dtfinal ) and bc.nr_atendimento=ab.nr_atendimento
, nvl ( ( select sum (ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, ''dd'') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146))) qtdeconsulta,
nvl ( ( select sum (ab.vl_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, ''dd'') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146)),0) totalconsulta,
from medico a where a.ie_vinculo_medico=''1'' and a.ie_corpo_clinico=''S'' and a.cd_pessoa_fisica <> ''230''
)
t order by t.nomemedico group by nomemedico;
Responder

02/03/2019

Diego

Olá Ricardo, tudo bem?

Obrigado pela resposta.

Sim, estou tentando somar dois resultados, o valoreq da 1a consulta (que faz sum no vl_procedimento) e o valoreq da 2a consulta (que faz sum no vl_material).
Todos os outros itens estão atendendo bem, somente a soma do valoreq que preciso alterar, pois quero considerar nessa coluna a soma desses dois resultados.
Vou dar um exemplo:

select sum(total) from (select sum( ab.vl_procedimento) total from procedimento_paciente ab where trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)
UNION ALL
select sum(TOTAL) from (select sum(vl_material) total, nr_atendimento from material_atend_paciente where trunc(dt_atendimento) between :dtinicial and :dtfinal group by nr_atendimento))

Esse código individualmente funciona bem, traz a soma de todo vl_procedimento e de todo vl_material como TOTAL. O que preciso é fazer o mesmo com o valoreq, mas obedecendo as cláusulas.

O sql original, que postei no tópico, atende bem...
Tudo que preciso é somar o sum(vl_material) também no bloco que traz o valoreq, porém, quando o nr_atendimento de cada tabela for igual, por isso do ab.nr_atendimento=bc.nr_atendimento.Entende?
O valoreq teria que ser a soma dos valores das duas tabelas, como no exemplo que fiz ali individualmente com o "total". Mas todas as formas que tentei encaixar o union all para o segundo select, me gerou erro de sintaxe...
Responder

02/03/2019

Diego

Tentei também usar dentro do mesmo sum, como no exemplo abaixo...

select t.nomemedico, t.qtdereq, t.valoreq, t.qtdeconsulta, t.totalconsulta, round(t.valoreq / nullif(t.qtdeconsulta,0),2) resultado, t.qtdetaxa, t.valortaxa from (
select a.nm_guerra nomemedico,
COALESCE( (select sum(ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_req = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)),0) qtdereq,
COALESCE ( ( select sum( ab.vl_procedimento + bc.vl_material ) from  procedimento_paciente ab LEFT JOIN material_atend_paciente bc ON ab.nr_atendimento=bc.nr_atendimento where ab.cd_medico_req = a.cd_pessoa_fisica and  trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
 and  ab.cd_procedimento not in (10101012,10101039,99999903,10106146,60000325)),0) valoreq, 

COALESCE ( ( select sum (ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146)),0) qtdeconsulta,
COALESCE ( ( select sum (ab.vl_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (10101012,10101039,99999903,10106146)),0) totalconsulta,
COALESCE ( ( select sum (ab.qt_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (60000325)),0) qtdetaxa,
COALESCE ( ( select sum (ab.vl_procedimento) from procedimento_paciente ab where ab.cd_medico_executor = a.cd_pessoa_fisica and trunc( ab.dt_procedimento, 'dd') between :dt_inicial and :dt_final
and ab.cd_motivo_exc_conta is null and ab.cd_procedimento in (60000325)),0) valortaxa
from medico a where a.ie_vinculo_medico='1' and a.ie_corpo_clinico='S' and a.cd_pessoa_fisica <> '230' order by a.nm_guerra) t

Porém a lógica não ficou correta e automaticamente os valores ficaram bem longe do esperado....
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar