Seleccionar por Fecha de Cumpleaños

454 views
Skip to first unread message

Alejandro Isla

unread,
Dec 11, 2012, 8:01:56 AM12/11/12
to publice...@googlegroups.com
Hola, les pido una ayuda: con VFP9 y una base de datos MySQL donde tengo un campo con la fecha de nacimiento (date).
La ideas es determinar las personas que cumplen años dentro de los xx días a partir de la fecha, es decir 

FechaInicial = Date()
Fechafinal = Date()+xx

Por lo general comparando mes y día de las fechas logro el cometido (desde y hasta contiene mes y día las fecha inicial y final en formato mmdd) cuando es dentro del mismo año

WHERE DATE_FORMAT(FecNac,'%m%d') between ?m.desde and ?m.hasta

El tema es ahora, a fin de año, cuando el periodo me incluye datos del año que viene, por ejemplo

FechaInicial = {11/12/2012}
FechaFinal = {11/01/2013}

comparar entre "1211" y "0111" lógicamente no arroja ningún resultado. Agregar el año no mejora nada ya que laa Fec. de Nac. tiene años muy variados.

Estoy dividiendo el periodo en dos (11/12/2012 al 31/12/2012 y 01/01/2013 al 11/01/2013), y utilizo el UNION de ambas consultas.

¿alguien tiene una forma más optima para hacerlo en una sola consulta?

Gracias.





Ricardo Pina

unread,
Dec 11, 2012, 8:24:26 AM12/11/12
to Grupo VFP
Hola Alejandro
 
Se me ocurre que puedes invertir las fechas y hacer la consulta por la negación
 
not Between( Fecha, "0111", "1211")
 
Creo que tendrias el resultado que buscas.
 
Saludos







--
 
 



--
            

                   Ricardo Pina

Desarrollo y Servicios Informáticos

                  Profesionales
               www.dsip.com.ar

 

 


Víctor Hugo Espínola Domínguez

unread,
Dec 11, 2012, 9:13:55 AM12/11/12
to publicesvfoxpro
Hola Alejandro


Prueba esto:


FechaInicial = {11/12/2012}
FechaFinal  = {11/01/2013}
m.Desde     = DTOS( FechaInicial )
m.Hasta      = DTOS( FechaFinal )
WHERE DATE_FORMAT(FecNac,'%Y%m%d') between ?m.desde and ?m.hasta

Saludos.
Víctor.

Víctor Hugo Espínola Domínguez

unread,
Dec 11, 2012, 9:21:15 AM12/11/12
to publicesvfoxpro
Hola Alejandro


También debería funcionar:

FechaInicial = {11/12/2012}
FechaFinal  = {11/01/2013}
m.Desde     =  FechaInicial
m.Hasta      =  FechaFinal
WHERE FecNac between ?m.desde and ?m.hasta

Esta forma es más clara y probablemente más eficiente.

Saludos.
Víctor.

Irwin Rodriguez

unread,
Dec 11, 2012, 9:55:05 AM12/11/12
to publice...@googlegroups.com
Alejandro, probaste lo siguiente:
 
SELECT * FROM tabla WHERE FECHA BETWEEN(FECHA1,FECHA2)
 
Saludos...!

Ricardo Pina

unread,
Dec 11, 2012, 11:13:23 AM12/11/12
to Grupo VFP
Alejandro
 
De mi post anterior toma la idea no la sintaxis que fue a modo de ejemplo
Victor / Irwin , lo que busca Alejandro es saber los que cumplen años desde la fecha de Nacimiento, por lo cual debe abstraer el año para llegar a un resultado correcto, sino solamente traeria los que nacieron ese año y no los demás.
 
Saludos


--
 
 

Irwin Rodriguez

unread,
Dec 11, 2012, 11:19:48 AM12/11/12
to publice...@googlegroups.com
Gracias por la aclaratoria Ricardo, no habia comprendido netamente lo que alejandro queria.
 
Saludos...!!!


 
--
 
 

Message has been deleted

Alejandro Isla

unread,
Dec 11, 2012, 1:08:22 PM12/11/12
to publice...@googlegroups.com
Muchas Gracias Ricardo, Funciona perfecto.

Dejo el código por si alguien necesita


m.CantDias  =  THISFORM.text1.VALUE && cantidad de días para analizar
m.Desde = DATE()
m.Hasta = DATE()+ m.CantDias
IF YEAR(m.Hasta) > YEAR(m.Desde) && FIN DE AÑO Y PRINCIPIO DEL SIGUIENTE
m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') NOT BETWEEN ?m.Hasta and ?m.Desde and CONTRATOS.mail>' '"
ELSE
m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') BETWEEN ?m.Desde and ?m.Hasta and CONTRATOS.mail>' '"
ENDIF
m.Desde = RIGHT(DTOS(m.Desde),4) && Solo tomo mes y día, como dijo ricardo, los años de nac. cambian
m.Hasta = RIGHT(DTOS(m.Hasta),4)
= SQLEXEC(Handle,"SELECT * FROM base " + m.Filtro, "CURSOR",aCountInfo)

Alejandro Isla

unread,
Dec 11, 2012, 1:09:49 PM12/11/12
to publice...@googlegroups.com
El martes, 11 de diciembre de 2012 10:24:26 UTC-3, Ricardo Pina escribió:
Hola Alejandro
 
Se me ocurre que puedes invertir las fechas y hacer la consulta por la negación
 
not Between( Fecha, "0111", "1211")
 
Creo que tendrías el resultado que buscas.
 
Saludos

Víctor Hugo Espínola Domínguez

unread,
Dec 11, 2012, 3:03:00 PM12/11/12
to publicesvfoxpro
Hola Alejandro

En primer lugar pido disculpa por el error, como bien lo ha señalado Ricardo.


>IF YEAR(m.Hasta) > YEAR(m.Desde) && FIN DE AÑO Y PRINCIPIO DEL SIGUIENTE
> m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') NOT BETWEEN ?m.Hasta and ?m.Desde and >CONTRATOS.mail>' '"

No te mostrará los que cumplen años el día de hoy, y los que cumplen en el último día del rango de fechas.

Debría quedar así:

m.CantDias  =  THISFORM.text1.VALUE && cantidad de días para analizar
m.Desde = DATE()
m.Hasta = DATE()+ m.CantDias
IF YEAR(m.Hasta) > YEAR(m.Desde) && FIN DE AÑO Y PRINCIPIO DEL SIGUIENTE
m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') NOT BETWEEN ?m.Hasta and ?m.Desde and CONTRATOS.mail>' '"
ELSE
m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') BETWEEN ?m.Desde and ?m.Hasta and CONTRATOS.mail>' '"
ENDIF
IF YEAR(m.Hasta) > YEAR(m.Desde) && FIN DE AÑO Y PRINCIPIO DEL SIGUIENTE
m.Hasta = m.Hasta + 1
m.Desde = m.Desde - 1
ENDIF
m.Desde = RIGHT(DTOS(m.Desde),4) && Solo tomo mes y día, como dijo ricardo, los años de nac. cambian
m.Hasta = RIGHT(DTOS(m.Hasta),4)
= SQLEXEC(Handle,"SELECT * FROM base " + m.Filtro, "CURSOR",aCountInfo)

Saludos.
Víctor.



El 11 de diciembre de 2012 14:08, Alejandro Isla <agi...@gmail.com> escribió:
m.CantDias  =  THISFORM.text1.VALUE && cantidad de días para analizar
m.Desde = DATE()
m.Hasta = DATE()+ m.CantDias
IF YEAR(m.Hasta) > YEAR(m.Desde) && FIN DE AÑO Y PRINCIPIO DEL SIGUIENTE
m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') NOT BETWEEN ?m.Hasta and ?m.Desde and CONTRATOS.mail>' '"
ELSE
m.Filtro = " WHERE DATE_FORMAT(tanacido,'%m%d') BETWEEN ?m.Desde and ?m.Hasta and CONTRATOS.mail>' '"
ENDIF
m.Desde = RIGHT(DTOS(m.Desde),4) && Solo tomo mes y día, como dijo ricardo, los años de nac. cambian
m.Hasta = RIGHT(DTOS(m.Hasta),4)
= SQLEXEC(Handle,"SELECT * FROM base " + m.Filtro, "CURSOR",aCountInfo)

Ricardo Pina

unread,
Dec 11, 2012, 3:22:21 PM12/11/12
to Grupo VFP
Hola Victor
 
No fue mi intención marcar el error.
Me imagine que no habian visto bien la cuestión.
 
Saludos


--
 
 

Víctor Hugo Espínola Domínguez

unread,
Dec 11, 2012, 3:37:58 PM12/11/12
to publicesvfoxpro
Hola Ricardo

No hay ni hubo molestia alguna, todo lo contrario ;-)

Saludos.
Víctor.



--
 
 

Alejandro Isla

unread,
Dec 14, 2012, 9:36:49 AM12/14/12
to publice...@googlegroups.com
Buena observación, gracias por la corrección.

Carlos Miguel FARIAS

unread,
Dec 14, 2012, 10:24:46 AM12/14/12
to publice...@googlegroups.com
Naci a muy temprana edad, y no sabía las fechas, asi que no pude seleccionar mi fecha de cumpleaños.
Y es viernes y no he visto una sonrisa (por lo menos en otro foro se invitaron a una chorizada).
Saludos: Miguel, Santa Rosa (LP)


El 14 de diciembre de 2012 11:36, Alejandro Isla <agi...@gmail.com> escribió:
Buena observación, gracias por la corrección.

--
 
 

mpulla

unread,
Dec 14, 2012, 5:40:40 PM12/14/12
to publice...@googlegroups.com

Hola Foxeros.

Yo me animaria a tratar los calculos como fechas, este codigo esta en Sql Server, si se animan lo pasan a MySql

Declare @dI date, @df date
Set @dI = '20121211'
Set @df = '20130105'

Declare @t Table (cNombre nVarchar(50), FNacimiento Date)
insert into @t
Values
('Juan Francisco', '20081213'),
('Maria Paula', '20060830'),
('Juan Diego', '19960103')

Select *
From
(
Select cNombre, fnacimiento,
       fcumple = iif(DATEADD(yy, Year(@dI) - Year(fnacimiento), FNacimiento) < @di
                   , DATEADD(yy, Year(@dI) - Year(fnacimiento) + 1, FNacimiento)
                   , DATEADD(yy, Year(@dI) - Year(fnacimiento), FNacimiento))
From @t
) s
Where s.fcumple between @dI and @df

Saludos.
Mauricio

Víctor Hugo Espínola Domínguez

unread,
Dec 15, 2012, 1:07:56 PM12/15/12
to publicesvfoxpro
Hola Mauricio

Visua FoxPro no tiene una función para adcionar años a una fecha, por lo tanto hay que usar GOMONTH():

    ldDesde = THISFORM.dDesde
    ldHasta  = THISFORM.dHasta
    SELECT  Employee.* ;
        FROM ( HOME( 2 ) + "\data\Employee" ) ;
        WHERE IIF(GOMONTH(Birth_Date, (YEAR(?ldDesde )-YEAR(Birth_Date))*12) < ?ldDesde ;
             , GOMONTH(GOMONTH(Birth_Date, (YEAR(?ldDesde )-YEAR(Birth_Date))*12), 12 )      ;
             , GOMONTH(Birth_Date, (YEAR(?ldDesde) - YEAR(Birth_Date))*12) )                 ;
        BETWEEN ?ldDesde AND ?ldHasta ;
        INTO CURSOR curEmployee READWRITE

MySql sí tiene la función: DATE_ADD() que tiene una sintaxis diferente a la de Sql Server.

Creo que la solución con datos tipo carácter es más legible, pero es una cuestión de gustos. Yo prefiero la que usa datos tipo fecha.

Saludos.
Víctor.



2012/12/14 mpulla <jmaur...@yahoo.es>

--
 
 

mpulla

unread,
Dec 15, 2012, 1:58:05 PM12/15/12
to publice...@googlegroups.com
Hola Victor.

En mi mensaje anterior exprese que era sintaxis para Sql Server y si se animan puden pasarla a MySql.

Por el resto como dices es cuestión de gustos.

Saludos.
Mauricio

Víctor Hugo Espínola Domínguez

unread,
Dec 15, 2012, 6:29:48 PM12/15/12
to publicesvfoxpro
Hola colegas

Adjunto versión para Firebird de la selección de cumpleañeros.

Saludos.
Víctor.



--
 
 

cumpleanosfb2.prg
Reply all
Reply to author
Forward
0 new messages