Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-03-2012
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Encontrar aniversarios

Buenos días a todos.

Mediante una consulta SQL con tablas Paradox necesito encontrar todas las filas de una tabla en las que su fecha de cumpleaños esté comprendida entre dos dadas que no tienen que ser necesariamente del mismo mes, por ejemplo del 28 de febrero al 2 de marzo. Cuando es una sola fecha no tengo problemas:
Código SQL [-]
SELECT * FROM 'Personas.db' 
WHERE EXTRACT(MONTH FROM F_nacimiento) = Mes AND EXTRACT(DAY FROM F_nacimiento) = Dia

Pero ¿cómo podría hacer la consulta cuando son fechas como en el caso que pongo?

Última edición por Casimiro Notevi fecha: 01-03-2012 a las 12:01:53.
Responder Con Cita
  #2  
Antiguo 01-03-2012
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.735
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
LA forma más sencilla es:
Código SQL [-]
SELECT * FROM 'Personas.db' 
WHERE 
F_nacimiento >= ?DesdeFecha and 
F_nacimiento <= ?HastaFecha
Responder Con Cita
  #3  
Antiguo 01-03-2012
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje

Código SQL [-]

SELECT * FROM 'Personas.db'
WHERE
F_nacimiento >= ?DesdeFecha and
F_nacimiento <= ?HastaFecha
No me vale, y no porque la idea sea mala. Yo tengo dos fechas, por ejemplo las que citaba antes; pero con la estructura que indicas sólo encontraría las del AÑO que se indicara en la fecha y yo necesito sacar las fichas de los cumplen años entre dos fechas de este año independientemente del año de nacimiento.

Última edición por Angel.Matilla fecha: 01-03-2012 a las 17:32:25. Razón: Al crearlo borré trozos por error
Responder Con Cita
  #4  
Antiguo 01-03-2012
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola
A ver asi:

Código SQL [-]
select * From  'Personas.db'
where extract(month from F_nacimiento) >= :mesini and extract(month from F_nacimiento) <= :mesfin
and extract(Day from F_nacimiento) >= :diaini and extract(Day from F_nacimiento) <= :diafin

Saludos
__________________
Siempre Novato
Responder Con Cita
  #5  
Antiguo 01-03-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Una aproximación:

Código SQL [-]
select * from 'personas.db'
where
  31*extract(month from F_nacimiento) + extract(day from F_nacimiento) between 31*:mes_i + :dia_i and 31*:mes_f+ :dia_f

Multiplicar el mes por 31 es necesario para los casos en que el día inicial es mayor que el final aunque el mes inicial se menor. Lo malo es que no sirve para intervalos de fechas que crucen el cambio de año.

// Saludos
Responder Con Cita
  #6  
Antiguo 01-03-2012
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Algo parecido hago yo:

Código Delphi [-]
procedure TfrAniversarios.FormActivate(Sender: TObject);
begin
DecodeDate(Date,aa,mm,dd);
DmClientes.IBDtsCli.Close;
DmClientes.IBDtsCli.SelectSQL.Clear;
DmClientes.IBDtsCli.SelectSQL.Add('Select * From Alumnos ');
DmClientes.IBDtsCli.SelectSQL.Add('Where Baja=''N''');
DmClientes.IBDtsCli.SelectSQL.Add('And Extract(Month from Fnacimiento)= :M');
DmClientes.IBDtsCli.SelectSQL.Add('And Extract(Day from Fnacimiento)  =  ');
DmClientes.IBDtsCli.ParamByName('M').AsString:=FormatFloat('00',mm);
DmClientes.IBDtsCli.ParamByName('D').AsString:=FormatFloat('00',dd);

DmClientes.IBDtsCli.Open;

end;
Un Saludo
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #7  
Antiguo 01-03-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
A como lo entiendo, la consulta de Caral debería dar los resultados correctos.
A la propuesta de roman no la he probado pero resulta interesante su forma.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #8  
Antiguo 02-03-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
debería dar los resultados correctos.
Esta consulta:

Código SQL [-]
select * From  'Personas.db'
where
  extract(month from F_nacimiento) >= :mesini and extract(month from F_nacimiento) <= :mesfin and
  extract(Day from F_nacimiento) >= :diaini and extract(Day from F_nacimiento) <= :diafin

no da resultados correctos. Vamos a aterrizar con unos datos específicos: 28 de febrero y 2 de marzo, que son los que ejemplifica Angel.Matilla.

La consulta queda así:

Código SQL [-]
select * From  'Personas.db'
where
  extract(month from F_nacimiento) >= 2 and extract(month from F_nacimiento) <= 3 and
  extract(Day from F_nacimiento) >= 28 and extract(Day from F_nacimiento) <= 2

Para F_nacimiento = 1 de marzo nos queda:

Código SQL [-]
select * From  'Personas.db'
where
  3 >= 2 and 3 <= 3 and
  1 >= 28 and 1 <= 2

La condición del primer renglón se cumple, mas no así la del segundo. Y sin embargo, el 1 de marzo sí está entre el 28 de febrero y el 2 de marzo.

// Saludos
Responder Con Cita
  #9  
Antiguo 02-03-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Pues hoy no le doy a nada ... ¡mi cabeza está muy apagada!

Tienes razón roman. ¿Y quizá tal vez no sería más apropiado evaluar sólo en cuanto al mes?

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #10  
Antiguo 02-03-2012
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Gracias a todos por las rspuestas. Voy por partes. En la propuesta de roman no entiendo lo de multiplicar por 31 el mes. En todo caso ¿No sría más lógico multiplicarlo por 100? Desa forma se formarían series desde 101 (1 de enero) al 1231 (31 de diciembre). Esta no se me había ocurrido y la tengo que probar.

La de marcoszorrilla es similar a la primera que me sugirieron pero, al igual que aquella, sólo extrae una fecha de todas las posibles.
Responder Con Cita
  #11  
Antiguo 02-03-2012
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Confirmado. El código ha quedado así:
Código SQL [-]
SELECT * FROM 'Personas.db' 
WHERE 100 * EXTRACT(MONTH FROM F_nacimiento) + EXTRACT(DAY FROM F_nacimiento) BETWEEN 100 * Mes_ini + Dia_ini AND 100 * Mes_fin + Dia_fin AND F_nacimiento != '12/30/1899'

Esa fecha final es porque en las tablas Paradox si una fecha se graba vacía por defecto pone el 30 de diciembre de 1788.

Última edición por Casimiro Notevi fecha: 02-03-2012 a las 10:02:10.
Responder Con Cita
  #12  
Antiguo 02-03-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Angel.Matilla Ver Mensaje
En la propuesta de roman no entiendo lo de multiplicar por 31 el mes. En todo caso ¿No sría más lógico multiplicarlo por 100?
Bueno, en realidad puedes multiplicarlo por 1000 o por 1000000. La idea es simplemente "agrandar" la parte del mes lo suficiente como para que la parte del día no domine en la comparación. De hecho, originalmente usé 100, pero en realidad 31 es suficiente. Es más, creo que 30 es suficiente

De todas formas, recuerda que este método va a fallar si, por ejemplo, quieres saber todos los cumpleaños entre el 28 de ciciembre y el 4 de enero.

// Saludos
Responder Con Cita
  #13  
Antiguo 02-03-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Para las fechas que "cruzan" de año, como el ejemplo de roman no queda más remedio que armar una condición del tipo:

Código SQL [-]
((:Mes >= Mes_ini) AND (:Mes <= 12)) OR ((:Mes >= 1) AND (:Mes <= Mes_fin))

De este modo se mostrarán aquellas fechas que sean desde el mes "inicial" hasta diciembre inclusive, más las fechas que sean de enero hasta la fecha "final".

Un criterio similar se puede, y debe, llevar a cabo con el tema los días "cruzados"

La cuestión es que ahora la lógica pasa por armar esta condición aplicando una evaluación previa de si el mes final es menor al inicial; y lo mismo aplica para el día.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #14  
Antiguo 02-03-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Bueno, se supone que todo mes es menor o igual que 12 y mayor o gual que 1, por lo que esos dos condicionales sobrarían.

Lo de la evaluación previa, creo que podemos hacerla en la misma consulta comparando los parámetros en sí:

Código SQL [-]
select * from personas
where
  ( 
    (100*:mi + :di < 100*:mf + :df) and
    (
      (100*:mi + :di < 100*extract(month from fecha) + extract(day from fecha)) and
      (100*extract(month from fecha) + extract(day from fecha) < 100*:mf + :df)
    )
  )
  or
  (
    (100*:mi + :di > 100*:mf + :df) and
    (
      (100*:mi + :di < 100*extract(month from fecha) + extract(day from fecha)) or
      (100*extract(month from fecha) + extract(day from fecha) < 100*:mf + :df)
    )
  )

Un ejemplo de uso:

Código Delphi [-]
var
  mi, mf, di, df: Integer;

begin
  Query1.ParamByName('mi').AsInteger := MonthOf(DateTimePickerInicial.Date);
  Query1.ParamByName('di').AsInteger := DayOf(DateTimePickerInicial.Date);

  Query1.ParamByName('mf').AsInteger := MonthOf(DateTimePickerFinal.Date);
  Query1.ParamByName('df').AsInteger := DayOf(DateTimePickerFinal.Date);

  Query1.Open;
end;

Conste que puse 100 para que no se extrañen .

No la he probado del todo pero creo que funciona salvo porque me falta el caso de que las fechas inicial y final sean iguales, pero no debe ser mayor problema.

// Saludos
Responder Con Cita
  #15  
Antiguo 03-03-2012
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
¿Ves? Eso no se me había ocurrido, lo de "agrandar" la parte del mes usando una cifra diferente de 100.

El otro problema, el del salto de año (p.ej.: del 28/12/2012 al 04/01/2013) en parte lo soluciono no permitiendo al operador que introduzca fechas superiores al 31 de diciembre del año en curso, pero es cierto que no es la mejor solución y hasta que vea otra opción...
Responder Con Cita
  #16  
Antiguo 05-03-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Angel.Matilla Ver Mensaje
El otro problema, el del salto de año (p.ej.: del 28/12/2012 al 04/01/2013)
Bueno, se supone que la última consulta que puse resuelve eso. ¿La has probado?

// Saludos
Responder Con Cita
  #17  
Antiguo 07-03-2012
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por roman Ver Mensaje
Bueno, se supone que la última consulta que puse resuelve eso. ¿La has probado?

// Saludos
Sí, lo probé pero con el código que puse yo también pude resolverlo. Gracias Roman.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Encontrar importe Waldo Varios 2 14-01-2010 19:39:08
Donde encontrar b0rn OOP 3 03-04-2007 01:05:22
Cómo encontrar Roilo Varios 1 07-12-2005 15:48:12
Encontrar la paz interior santana Humor 3 14-06-2004 18:47:35
encontrar el siguiente en ado jzginez Conexión con bases de datos 1 21-05-2004 11:42:08


La franja horaria es GMT +2. Ahora son las 19:20:24.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi