Pride_fns 0 Denunciar post Postado Junho 11, 2010 Bom dia pessoal do IMasters!!! Estou tentando fazer um CASE dentro da Cláusula WHERE e acontece o seguinte erro, "ORA-00920:operador relacional inválido" apontando para a segunda Condição do WHERE => "and cod_ben = 1821001". Não conseguir descobrir o porquê do erro. E também gostaria de saber se este é um método apropriao para se usar o CASE dentro do WHERE!! SELECT (....) FROM (....) WHERE CASE WHEN TO_CHAR(SYSDATE,'DD/MM/') < TO_CHAR(b.dtcad,'DD/MM/') THEN 'and a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad, DD/MM/) || (TO_CHAR(SYSDATE, YYYY)-1))' ELSE 'and a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad, DD/MM/) || (TO_CHAR(SYSDATE, YYYY)))' END and cod_ben = 1821001 and ROWNUM = 1; Quem puder ajudar com uma palhinha de sua experiência, fique a vontade!!! Vlw galera do IMasters pelo ótimo Fórum!!! Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 11, 2010 Não o CASE deve ser tratado como uma coluna ... WHERE (CASE WHEN DATA < TRUNC(SYSDATE) THEN 'ANTIGA' WHEN DATA = TRUNC9SYSDATE) THEN 'HOJE' ELSE 'FUTURA' END) = 'HOJE' ... Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 11, 2010 Obrigado mais uma vez Motta. Que pena, entendi mas... O que seria mais aconselhável para se usar nesses caso que quero fazer um teste para saber qual condição vou usar no WHERE? Seria algo como isso? OBS.: Eu uso este mesmo CASE no SELECT só que dentro do THEN e do ELSE faço SUBSELECT's.... (....) WHERE cod_ben = 1821001 and ((a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE,'YYYY')-1))) OR (a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE,'YYYY'))))) and a.dt_pagamento > a.dt_vencto and ROWNUM = 1; Se for necessário posto o SQL todo!!! Muito Obrigado Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 11, 2010 Não entendi, me desculpe. Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 11, 2010 Tudo bem, realmente não soube transmitir, por isso vo colocar todo o SQL e explicar mais detalhadamente. Como podem ver no SELECT faço um CASE para fazer SUBSELECT's separando o calculo de "Data Início do Ano Passado" e outro de "Data Início do Ano Atual". Então no WHERE também tenho que fazer o mesmo CASE que criei no SELECT porque para cada caso uso uma condição diferente. Como você explicou que não é possível utilizar o CASE deste modo, ainda não conseguir encontrar um outro método. E 1000 desculpas se ficou muito grande!!! SELECT cod_ben, CASE WHEN TO_CHAR(SYSDATE,'DD/MM/') < TO_CHAR(b.dtcad,'DD/MM/') THEN CASE WHEN TO_CHAR(a.dt_vencto - TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE,'YYYY')-1))) > 0 THEN ( SELECT SUM(a.dt_pagamento - a.dt_vencto) FROM sis.boleto_ben a INNER JOIN sis.benefics b USING(cod_ben) INNER JOIN sis.ativacao_ben c USING(cod_ben) WHERE c.dthr_final is null and b.cod_emp = 0 and cod_ben = 1821001 and a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE,'YYYY')-1)) and a.dt_pagamento > a.dt_vencto and a.vlr_pago > a.vlr_boleto ) END ELSE CASE WHEN TO_CHAR(a.dt_vencto - TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE,'YYYY')))) > 0 THEN ( SELECT SUM(a.dt_pagamento - a.dt_vencto) FROM sis.boleto_ben a INNER JOIN sis.benefics b USING(cod_ben) INNER JOIN sis.ativacao_ben c USING(cod_ben) WHERE c.dthr_final is null and b.cod_emp = 0 and cod_ben = 1821001 and a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE,'YYYY'))) and a.dt_pagamento > a.dt_vencto and a.vlr_pago > a.vlr_boleto ) END END qntd_acum FROM sis.boleto_ben a INNER JOIN sis.benefics b USING(cod_ben) INNER JOIN sis.ativacao_ben c USING(cod_ben) WHERE CASE WHEN TO_CHAR(SYSDATE,'DD/MM/') < TO_CHAR(b.dtcad,'DD/MM/') THEN 'and a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad, DD/MM/) || (TO_CHAR(SYSDATE, YYYY)-1))' ELSE 'and a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad, DD/MM/) || (TO_CHAR(SYSDATE, YYYY)))' END and cod_ben = 1821001 and ROWNUM = 1 Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 11, 2010 Este SQL está montando outro SQL ? Pq alguns comandos estão entre aspas ? Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 12, 2010 Este SQL está montando outro SQL ? Pq alguns comandos estão entre aspas ? 1) É um SQL único! 2) Coloquei entre aspas apenas os itens dentro da função TO_CHAR pq foi assim que vi em exemplos na net! >>> TO_CHAR(b.dtcad,'DD/MM/') = nesse caso so pego o dia/mês da data pra futuramente concatenar com um dos anos a depender do CASE que entrar no SELECT. E também no THEN e ELSE do CASE do WHERE mas esse não vai contar pq está errado ne!! ^^ Mais uma vez, sei pouco em SQL, e o que aprendir inicialmente foi Postgre.Agora estou começando a usar o ORACLE!!! Então não estou familiarizado como as funções são escritas! Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 12, 2010 A ideia básica do CASE é transformar um ou mais campos da tabela. Linhas em colunas SELECT (CASE WHEN FORMA_PGTO = 'CARTAO' THEN VALOR ELSE 0 END) CARTAO, (CASE WHEN FORMA_PGTO = 'DINHEIRO' THEN VALOR ELSE 0 END) DINHEIRO, (CASE WHEN FORMA_PGTO NOT IN ('CARTAO','DINHEIRO') THEN VALOR ELSE 0 END) OUTROS FROM TABELA Mudar colunas SELECT (CASE WHEN DATA < TRUNC(SYSDATE) THEN 'ANTIGA' WHEN DATA = TRUNC9SYSDATE) THEN 'HOJE' ELSE 'FUTURA' END) = 'HOJE') TIPO_DATA FROM TABELA Entre outros tratamentos Dá uma lida nisto. Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 13, 2010 A ideia básica do CASE é transformar um ou mais campos da tabela. Linhas em colunas SELECT (CASE WHEN FORMA_PGTO = 'CARTAO' THEN VALOR ELSE 0 END) CARTAO, (CASE WHEN FORMA_PGTO = 'DINHEIRO' THEN VALOR ELSE 0 END) DINHEIRO, (CASE WHEN FORMA_PGTO NOT IN ('CARTAO','DINHEIRO') THEN VALOR ELSE 0 END) OUTROS FROM TABELA Mudar colunas SELECT (CASE WHEN DATA < TRUNC(SYSDATE) THEN 'ANTIGA' WHEN DATA = TRUNC9SYSDATE) THEN 'HOJE' ELSE 'FUTURA' END) = 'HOJE') TIPO_DATA FROM TABELA Entre outros tratamentos Dá uma lida nisto. Certo, eu já tinha entendido isso do CASE, pelo menos creio que estou fazendo certo no CASE do SELECT neh!!!? pq faço tipo assim: Vamos criar uma Data só com dia/mês =>> dtcad := 22/08; e um Valor qualquer =>> A := 5; SELECT (...) CASE WHEN TO_CHAR(SYSDATE,'DD/MM/') < TO_CHAR(dtcad) THEN CASE WHEN A > 2 THEN (SELECT pra pegar um SUM qualquer menos 1) [EX.: (5+3)-1 = 7] END ELSE CASE WHEN A > 0 THEN (SELECT pra pegar um SUM qualquer) [EX.: (5+3) = 8] END END VALIDACAO (....) Agora no WHERE ele terá que fazer esse teste, SE lá no CASE do SELECT ele entrar na condição 'A > 2' irá entrar em uma condição X do WHERE [5+3)-1 = 7], SENÃO irá entrar em uma condição Y do WHERE [(5+3) = 8]. Este teste no WHERE que não sei como terei que fazer, porquê ele não tem como fazer as duas condições pois vai dar erro pq nao tem como ele ser 'A > 2' e 'A < 2' ao mesmo tempo. OBS.: perceba que no meu Post anterior, onde coloquei todo o meu SQL, que utilizo da concatenação do (ano_atual -1) em um CASE e no outro só concateno o (ano_atual), nisso é que irei descobrir qual será a data inicial de onde irei fazer os calculos. Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 13, 2010 O Case poderia ser unido. SELECT (...) CASE WHEN (TO_CHAR(SYSDATE,'DD/MM/yyyy') < TO_CHAR(dtcad) and A > 2 THEN (SELECT pra pegar um SUM qualquer menos 1) WHEN (TO_CHAR(SYSDATE,'DD/MM/yyyy') >= TO_CHAR(dtcad) and A > 0 THEN (SELECT pra pegar um SUM qualquer) ELSE (...) END VALIDACAO Só não entendi o motivo deste select dentro do CASE. Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 13, 2010 Bem, não expliquei porque prolongaria o post, mas se for o caso explicarei o SQL: É feito o Cadastro de uma pessoa no Plano de Saúde dia '01/01/2001' será gerado o boleto sempre com Vencimento dias 10 de cada mês(PS.: nem sempre é dia 10). Então serão os dias: 10/01/2001 10/02/2001 10/03/2001 (.....) Vou ter que somar em cada mês os dias atrasados, por exemplo: JAN dt_boletoJAN = 10/01/2010 dt_pgtoJAN = 12/01/2010 dt_pgtoJAN - dt_boletoJAN = 2 (dias de atraso) dias_atraso_total = 2 [dias de atraso total] FEV dt_boletoFEV = 10/02/2010 dt_pgtoFEV = 15/02/2010 dt_pgtoFEV - dt_boletoFEV = 5 (dias de atraso) dias_atraso_JAN + dias_atraso_FEV = 2 + 5 = 7 E quando essa soma ultrapassar 60 dias de atraso até o aniversário do cliente, ou seja, no dia 01/01/2002 a empresa poderá cancelar o contrato. Mas todo dia de aniversário, ou seja, 01/01/2002 ... 01/01/2003 ... 01/01/2004 ... e assim por diante, começará a ser contado os dias de atraso novamente do 0(ZERO). Por exemplo: se no dia 31/12/2003 ele tiver a soma de dias atrasados igual a 59 no dia 01/01/2004 terá 0 dias de atraso porque começará a contar novamente só que para o novo período que será de dia 01/01/2004 à 31/12/2004. Por isso pego o dia/mes da data de cadastro e testo se é maior que a data atual, para descobrir em qual período vou começar a contar. POr exemplo: A data de cadastro foi dia '22/08/2001'; A data atual é '13/06/2010'; *separo o dia/mÊs das datas; SE 22/08 > 13/06 já sei que a data inicial pra fazer as somas será 22/08/2009; SENÂO a data inicial pra fazer as somas será 22/08/2010. Por isso quebro o Ano da data, para depois Concatenar com o Ano que quero. Isso que o SELECT do CASE faz: SE entrar no THEN faz o cálculo de soma onde data_boleto >= '22/08/2009'; SENÂO faz o cálculo de soma onde data data_boleto >= '22/08/2010'; Logo no WHERE ele terá que fazer um tipo de teste mais ou menos assim: WHERE CASE WHEN 22/08 > 13/06 THEN 'data_boleto >= 22/08/2009' ELSE 'data_boleto >= 22/08/2010' END Obrigado por estar tentando me ajudar!!! Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 14, 2010 Supondo que CLIENTE.VIGENCIA seja a vigência atual do cidadão ... Pois os boletos anteriores a vigência não consta mais. Seria +ou- isto. SELECT CLIENTE.NOME, BOLETO.REFERENCIA, (CASE WHEN (NVL(BOLETO_DT_PGTO,TRUNC(SYSDATE)) > BOLETO.DT_VENCIMENTO)) THEN (NVL(BOLETO_DT_PGTO,TRUNC(SYSDATE)) - BOLETO.DT_VENCIMENTO) ELSE 0 END) DIAS_ATRASO FROM CLIENTE,BOLETOS WHERE BOLETO.REFERENCIA <= ADD_MONTHS(CLIENTE.VIGENCIA,12) SELECT CLIENTE.NOME, SUM( (CASE WHEN (NVL(BOLETO_DT_PGTO,TRUNC(SYSDATE)) > BOLETO.DT_VENCIMENTO)) THEN (NVL(BOLETO_DT_PGTO,TRUNC(SYSDATE)) - BOLETO.DT_VENCIMENTO) ELSE 0 END) ) DIAS_ATRASO FROM CLIENTE,BOLETOS WHERE BOLETO.REFERENCIA <= ADD_MONTHS(CLIENTE.VIGENCIA,12) GROUP BY CLIENTE.NOME PS Trabalho com Plano de Saúde também. Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 14, 2010 hehehe .... que coincidencia!!! ^^ Motta desculpa a minha ignorância, mas como já disse sou inexperiente na área. Mas... 1º) O que você consegue pegar aki? eu sei que o NVL troca um valor NULL pelo que a gnt kiser, mas não entendi pra que serve desse jeito que tu colocou!!!????? NVL(BOLETO_DT_PGTO,TRUNC(SYSDATE)) 2º) Também não conseguir entender o que seria o CLIENTE.VIGENCIA (data_hoje?) 3º) E o BOLETO.REFERENCIA (data_vencimento do boleto?) 4º) Se faz com dois SELECTS mesmo? Porquê você só faz o SUM no segundo SELECT se são praticamente iênticos, com excessão de um item no select e o group by? Sinceramente trabalhar com Data é muuuito trabalhoso!!! hehehe Muito Obrigado Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 14, 2010 1º) O que você consegue pegar aki? eu sei que o NVL troca um valor NULL pelo que a gnt kiser, mas não entendi pra que serve desse jeito que tu colocou!!!????? NVL(BOLETO_DT_PGTO,TRUNC(SYSDATE)) Se estiver em aberto (data nula) conta os dias até o data corrente da execução 2º) Também não conseguir entender o que seria o CLIENTE.VIGENCIA (data_hoje?) Não, seria a data da vigência do contrato do usuário, se renovou em 01/02/2010 passa a ser esta data. 3º) E o BOLETO.REFERENCIA (data_vencimento do boleto?) Não, a referência (ano e mês) relativos ao mês cobrança do boleto. 4º) Se faz com dois SELECTS mesmo? O que você pega em cada um? Não, foram apenas dois exemplos. Compartilhar este post Link para o post Compartilhar em outros sites
Pride_fns 0 Denunciar post Postado Junho 17, 2010 Graças a Deus conseguir resolver este maldito bendito SQL!!! Também Depois de 2 semanas e meia neh!!! Tinha que sair Muito obrigado pela ajuda Motta, e tudo de bom ae pro teu job, porque no meu ta pegando... hehehe http://forum.imasters.com.br/public/style_emoticons/default/joia.gif Compartilhar este post Link para o post Compartilhar em outros sites