- Este tópico contém 9 respostas, 4 vozes e foi atualizado pela última vez 15 anos, 9 meses atrás por
pride_fns.
-
AutorPosts
-
11 de junho de 2010 às 8:36 pm #94537
pride_fns
ParticipanteBoa Tarde pessoal do GPO, sou novato no SQL e estou tendo uma dificuldade onde preciso fazer um teste dentro da cláusula WHERE.
Eu sei que está errado usando o CASE deste modo, mas é só para vcs teream uma idéia da situação:
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;OBS.: Eu uso este mesmo CASE no SELECT só dentro do THEN e ELSE faço SUBSELECT’s….
Se quiserem posto o SQL todo.
Obrigado a quem puder compartilhar um pouco da sua experiência neste tópico!!
11 de junho de 2010 às 8:46 pm #94538rwarstat
ParticipantePosta exatamente o quê tu queres fazer, bem como o sql que tu fez e exemplo das tabelas. Assim fica bem mais fácil te ajudar.
Só vendo aquele trecho de código não consegui entender a tua dificuldade.
Abraço,
Roberto11 de junho de 2010 às 10:14 pm #94541pride_fns
ParticipanteTudo 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 descobrir 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!!!
[sql]
SELECT cod_ben,
CASE WHEN TO_CHAR(SYSDATE,’DD/MM/’) 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_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 ((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 ROWNUM = 1
[/sql]11 de junho de 2010 às 10:19 pm #94542pride_fns
ParticipanteOPS… IGNORE a penúltima Condição do WHERE principal:
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’)))))
ela ainda não existe ( é teste ).
11 de junho de 2010 às 11:13 pm #94544rwarstat
ParticipanteConsegue a estrutura das tabelas e algumas linhas para fazer teste?
É mais fácil fazer com os dados que tu tá usando do que a gente imaginando.Abraço,
Roberto11 de junho de 2010 às 11:29 pm #94546fsitja
ParticipanteOlá,
Me desculpe, mas não consegui entender o que você quer obter nesse select. Em vez de postar aquilo que você pensou como solução vamos abordar o problema que você precisa solucionar. Vamos começar do início:
– Poste sua versão do Oracle por favor, pois a solução pode mudar de versão para versão;
– Uma breve explicação em alto nível, do que se quer alcançar com esse SQL.
– A estrutura das tabelas boleto_ben, benefics e ativacao_ben e qualquer outra que sejam necessárias (create tables ajudam)
– Dados de exemplo (inserts) para que possamos testar a proposta de solução
– O layout e o que você quer que o select exiba (linhas x colunas) usando os dados de exemplo para mostrar o que deve aparecer.Abraço,
Francisco12 de junho de 2010 às 12:54 am #94550burga
ParticipantePra isso que você está querendo nem precisa do CASE no WHERE…
Faz mais ou menos assim:
WHERE
((TO_CHAR(SYSDATE,'DD/MM/') = TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE, 'YYYY')-1)))
OR
(TO_CHAR(SYSDATE,'DD/MM/') >= TO_CHAR(b.dtcad,'DD/MM/')
AND a.dt_vencto >= TO_DATE(TO_CHAR(b.dtcad,'DD/MM/') || (TO_CHAR(SYSDATE, 'YYYY'))))
AND cod_ben = 1821001
AND ROWNUM = 1;
Ou coisa parecida… Espero que tenha entendido!
12 de junho de 2010 às 1:21 am #94552fsitja
ParticipanteEssa comparação provavelmente está incorreta no código do Pride:
TO_CHAR(SYSDATE,'DD/MM/') < TO_CHAR(b.dtcad,'DD/MM/')
Acho que o que ele quer seria
TO_CHAR(SYSDATE,'MMDD') < TO_CHAR(b.dtcad,'MMDD')
Mas para ter certeza só ele explicando qual a lógica que precisa, em termos de requisito de usuário.
12 de junho de 2010 às 2:47 am #94554burga
Participante[quote=”fsitja”:dq3gkx1p]Essa comparação provavelmente está incorreta no código do Pride:
TO_CHAR(SYSDATE,'DD/MM/') < TO_CHAR(b.dtcad,'DD/MM/')
Acho que o que ele quer seria
TO_CHAR(SYSDATE,'MMDD') < TO_CHAR(b.dtcad,'MMDD')
Mas para ter certeza só ele explicando qual a lógica que precisa, em termos de requisito de usuário.[/quote]
Verdade, não reparei nesta cláusula, desculpa pela falta de atenção 😆 .
Se a lógica da consulta inicial estiver correta é só fazer mais esta correção que o problema estará resolvido.
14 de junho de 2010 às 2:53 pm #94560pride_fns
ParticipanteBem, 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 [dias de atraso total]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_boleto >= ’22/08/2010′;Logo no WHERE ele terá que fazer um tipo de teste mais ou menos assim:
(….)
WHERE cod_ben = 1821001
CASE WHEN 22/08 > 13/06
THEN
‘and data_boleto >= 22/08/2009’
ELSE
‘and data_boleto >= 22/08/2010’
END
and ROWNUM = 1 -
AutorPosts
- Você deve fazer login para responder a este tópico.