Oracle - invalid number of arguments com NVL + UNION ALL
01/03/2019
0
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!
Diego
Posts
02/03/2019
Ricardo Pestana
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;
02/03/2019
Diego
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...
02/03/2019
Diego
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....
Clique aqui para fazer login e interagir na Comunidade :)