Aniversariantes

Delphi

28/02/2005

TEnho um formulario q esta usando um SQl para pesquisar usuarios q fazem aniversario entre duas datas q o usuario informa, o sql q estou isando eh esse:

WHERE ((EXTRACT(MONTH FROM Usu_nascimento) = :MES1) AND (EXTRACT(DAY FROM Usu_nascimento) >= :DIA1)) OR ((EXTRACT(MONTH FROM Usu_nascimento) = :MES2) AND (EXTRACT(DAY FROM Usu_nascimento) <= :DIA2)) OR ((EXTRACT(MONTH FROM Usu_nascimento) > :MES1) AND (EXTRACT(MONTH FROM Usu_nascimento) < :MES2))


mas quando o kra informa duas datas iguais o sql mostra varios registros q naum tem nada haver, com o q eh pedido.

Alguem teria alguma outra solução para esse problema, ou corrigir esse comando no meu sql.


Zunker

Zunker

Curtidas 0

Respostas

Koplin

Koplin

28/02/2005

where
((EXTRACT(DAY FROM Usu_nascimento) >= :DIA1) AND
(EXTRACT(MONTH FROM Usu_nascimento) >= :MES1))
and ((EXTRACT(DAY FROM Usu_nascimento) <= :DIA2) AND
(EXTRACT(MONTH FROM Usu_nascimento) <= :MES2))


GOSTEI 0
Zunker

Zunker

28/02/2005

Neste caso vai acontecer mesma coisa q o outro sql, quando o usuario informar duas datas iguais....xD


GOSTEI 0
Zunker

Zunker

28/02/2005

Antigamente eu usava deste jeito:

WHERE (extract(month from Usu_nascimento) BETWEEN :mes1 AND :mes2) and (extract(day from Usu_nascimento) between :dia1 and :dia2)


Soh q dai se tu informava um valor por exemplo entre 28/02 e 01/03, dai eh como se naum tivesse Aniversariantes nestas datas sendo q tem +/- uns 300 usuarios q fazem aniversario nesse intervalo.....xD


GOSTEI 0
Beppe

Beppe

28/02/2005

E assim: :roll:
WHERE (EXTRACT(MONTH FROM Usu_nascimento) between :MES1 and :MES2) and
(((EXTRACT(MONTH FROM Usu_nascimento) = :MES1 and EXTRACT(DAY FROM Usu_nascimento) >= :DIA1) or
((EXTRACT(MONTH FROM Usu_nascimento) = :MES2 and EXTRACT(DAY FROM Usu_nascimento) <= :DIA2)))



GOSTEI 0
Motta

Motta

28/02/2005

Converta a data da tabela para um ano padrao e teste em cima deste ano, fica uma passagem simples de parametros, o único problema é tratar um intervalo entre anos 25/dez a 06/jan, mas isto pode ser resolvido por um union 25 a 31 e 01 a 06.


GOSTEI 0
Zunker

Zunker

28/02/2005

E assim: :roll:
WHERE (EXTRACT(MONTH FROM Usu_nascimento) between :MES1 and :MES2) and
(((EXTRACT(MONTH FROM Usu_nascimento) = :MES1 and EXTRACT(DAY FROM Usu_nascimento) >= :DIA1) or
((EXTRACT(MONTH FROM Usu_nascimento) = :MES2 and EXTRACT(DAY FROM Usu_nascimento) <= :DIA2)))


Neste caso esta quase certo pois se o kra informa as mesmas datas soh informa todos do mesmo mes, mas naum chega a informa todos soh da data, por exemplo se ele informar 07/03 e 07/03.

E motta eu naum entendi a sua explicação, pois nunca mexi desta maneira, naumteria um exemplo pra me explicar melhor.

Desde jah obrigado pela atenção....xD


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/02/2005

tente assim:

WHERE (Extract(MONTH from Usu_nascimento) between :Mes1 and :Mes2)
  and ((Extract(MONTH from Usu_nascimento) = :Mes1
            and Extract(DAY from Usu_nascimento) >= :Dia1) or 
       (Extract(MONTH from Usu_nascimento) = :Mes2 
            and Extract(DAY from Usu_nascimento) <= :Dia2) or
       (Extract(MONTH from Usu_nascimento)<>:Mes1 
            and Extract(MONTH from Usu_nascimento)<>:Mes2)
      )



GOSTEI 0
Zunker

Zunker

28/02/2005

tente assim:
WHERE (Extract(MONTH from Usu_nascimento) between :Mes1 and :Mes2)
  and ((Extract(MONTH from Usu_nascimento) = :Mes1
            and Extract(DAY from Usu_nascimento) >= :Dia1) or 
       (Extract(MONTH from Usu_nascimento) = :Mes2 
            and Extract(DAY from Usu_nascimento) <= :Dia2) or
       (Extract(MONTH from Usu_nascimento)<>:Mes1 
            and Extract(MONTH from Usu_nascimento)<>:Mes2)
      )


Neste caso

(Extract(MONTH from Usu_nascimento)<>:Mes1 
            and Extract(MONTH from Usu_nascimento)<>:Mes2)


seria descartado, pois tu jah vai tar definindo em

(Extract(MONTH from Usu_nascimento) between :Mes1 and :Mes2)


Entaum seria o mesmo q este esquema q jah foi passado aki no topico

WHERE (EXTRACT(MONTH FROM Usu_nascimento) between :MES1 and :MES2) and
(((EXTRACT(MONTH FROM Usu_nascimento) = :MES1 and EXTRACT(DAY FROM Usu_nascimento) >= :DIA1) or
((EXTRACT(MONTH FROM Usu_nascimento) = :MES2 and EXTRACT(DAY FROM Usu_nascimento) <= :DIA2)))


Mas mesmo assim obrigado pela atenção


GOSTEI 0
Motta

Motta

28/02/2005

sou meio bitolado no sql do Oracle pois fui o único que usei

temos duas funcoes

to_char - converte uma data para string

to_date - ´ uma string para data

seria algo assim

SELECT *
FROM CADASTRO
WHERE TO_DATE(TO_CHAR(DATA_NASCIMENTO,´DDMM´)||´1900´,´DDMMYYYY´)
BETWEEN TO_DATE(´01021900´,´DDMMYYYY´) AND TO_DATE(´15031900´,´DDMMYYYY´)


O PROBLEMA SERIA ALGO DO TIPO ENTRE ANOS
QUE PODERIA SER RESOLVIDO POR UM UNION

SELECT *
FROM CADASTRO
WHERE TO_DATE(TO_CHAR(DATA_NASCIMENTO,´DDMM´)||´1900´,´DDMMYYYY´)
BETWEEN TO_DATE(´25121900´,´DDMMYYYY´) AND TO_DATE(´31121900´,´DDMMYYYY´)
UNION ALL
SELECT *
FROM CADASTRO
WHERE TO_DATE(TO_CHAR(DATA_NASCIMENTO,´DDMM´)||´1900´,´DDMMYYYY´)
BETWEEN TO_DATE(´01011900´,´DDMMYYYY´) AND TO_DATE(´06011900´,´DDMMYYYY´)


Sou pouco didatico, mas entendeu ?


GOSTEI 0
Zunker

Zunker

28/02/2005

Eu nunca usei o Oracle, por isso talvez naum conheça essas funções, eu teria q ver se tem algo parecido com elas no InterBase, mas assim entendi a sua explicação.


GOSTEI 0
Motta

Motta

28/02/2005

Acho que a CAST, mas não sei a sintaxe direito, tente o forum de IB/FB.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/02/2005

no caso, Motta, não bastaria fazer

SELECT *
FROM CADASTRO
WHERE TO_CHAR(DATA_NASCIMENTO,´MMDD´) // invertido mesmo
BETWEEN TO_CHAR(:DataIni,´MMDD´) AND TO_CHAR(:DataFim,´MMDD´)

?

creio que assim funcione (no Oracle), pois assim seriam exibidos todos os aniversariantes independente do ano.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/02/2005

olha a gambiarra:

instrução SQL para o IB/FB:
select * from usuarios
where extract(month from nascimento) + (cast(extract(day from nascimento) as numeric(5,2)) / 100)
between :Param1 and :Param2

no delphi, via passagem de parâmetros:
Params.ParamByName(´Param1´).AsString := FormatDateTime(´MM.DD´,Data);
Params.ParamByName(´Param2´).AsString := FormatDateTime(´MM.DD´,Data);
obs.: os parâmetros devem ser passados como [b:d7852409e7]AsString[/b:d7852409e7] mesmo.

ou direto:
select * from usuarios
where extract(month from nascimento) + (cast(extract(day from nascimento) as numeric(5,2)) / 100)
between 02.25 and 02.28

onde 02.25 e 02.28 é a data no formato MM.DD (obviamente, é um float)


GOSTEI 0
Motta

Motta

28/02/2005

testei, não funcionou na ´virada´, creio que pela string do mes.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/02/2005

humm... teoricamente deveria funcionar...

mas agora fiquei com uma dúvida:
[b:36bea54277]Zunker[/b:36bea54277], como a data é informada pelo usuário? Dia/Mês ou uma data completa, Dia/Mês/Ano?


GOSTEI 0
Zunker

Zunker

28/02/2005

Dia/Mês e Dia/Mês


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/02/2005

ah, certo. então creio que o último código que te passei

[i:cfba9c8705]instrução SQL para o IB/FB:
select * from usuarios
where extract(month from nascimento) + (cast(extract(day from nascimento) as numeric(5,2)) / 100)
between :Param1 and :Param2

no delphi, via passagem de parâmetros:
Params.ParamByName(´Param1´).AsString := FormatDateTime(´MM.DD´,Data);
Params.ParamByName(´Param2´).AsString := FormatDateTime(´MM.DD´,Data);
obs.: os parâmetros devem ser passados como AsString mesmo.

ou direto:
select * from usuarios
where extract(month from nascimento) + (cast(extract(day from nascimento) as numeric(5,2)) / 100)
between 02.25 and 02.28

onde 02.25 e 02.28 é a data no formato MM.DD (obviamente, é um float)[/i:cfba9c8705]

deva funcionar, porque não há ´virada´ como sugeriu o Motta. Assim, a consistência deverá ficar no programa, para que não aceite intervalos como 05/12 a 05/01. ou seja, o programa deve consistir as datas de modo a serem sempre crescentes.


GOSTEI 0
Zunker

Zunker

28/02/2005

Gostei de todas as idéias q foram postadas aki, vou testar essa q tu postou, mas jah consegui ajeitar aki naum importando a data q o kra informa, mas ficou uma zona por isso prefiro nem postar aki a solução, sendo q essa solução foi tirada da idéia de cada um q postou aki, entaum obrigado a todos pela colaboração.....xD


GOSTEI 0
Steve_narancic

Steve_narancic

28/02/2005

bem e se o intervalo informado for entre dois anos diferentes.
Ex.: Retornar os aniversariantes do periodo de 1/12/2005 à 15/02/2006 tem como fazer?


GOSTEI 0
Steve_narancic

Steve_narancic

28/02/2005

bem e se o intervalo informado for entre dois anos diferentes. Ex.: Retornar os aniversariantes do periodo de 1/12/2005 à 15/02/2006 tem como fazer?



[b:9d6f252327]RESOLVIDO:[/b:9d6f252327]
Testo se a intervalo de datas entre dois anos diferentes, se sim aplico o seguinte filtro:

And ((extract(month from DT_NASC) + (cast(extract(day from DT_NASC) as numeric(5,2)) / 100) between :Dt_inicial and 12.31)
or  ((extract(month from DT_NASC) + (cast(extract(day from DT_NASC) as numeric(5,2)) / 100) between 01.01 and :dt_final)))



GOSTEI 0
POSTAR