Jump to content


Photo

Problema consulta BETWEEN fechas en Access


  • Please log in to reply
7 replies to this topic

#1 amell2020

amell2020

    Advanced Member

  • Miembros
  • PipPipPip
  • 340 posts
  • LocationEn un solo Lugar

Posted 07 March 2012 - 09:12 PM

hola amigos que tal de nuevo, estoy realizando un sistema de control de hora y llega de un personal de una empresa, pero resulta que tengo problema a la hora de consultar las fechas de entradas y salida de un personal.

este es el codigo de la consulta:


delphi
  1. adoquery1.Close;
  2. adoquery1.SQL.Text:= 'SELECT * FROM datos WHERE condicion = :Condicion '+
  3. 'AND fecha BETWEEN :Desde AND :Hasta';
  4. if Trim(edit1.Text) <> '' then
  5. begin
  6.   adoquery1.SQL.Add(' AND codigo = :Codigo');
  7.   adoquery1.Parameters.ParamByName('Codigo').Value := edit1.text;
  8. end; 
  9. adoquery1.Parameters.ParamByName('Condicion').Value := Combobox1.Text;
  10. adoquery1.Parameters.ParamByName('Desde').Value := Datetimepicker1.DateTime;
  11. adoquery1.Parameters.ParamByName('Hasta').Value := Datetimepicker2.DateTime;
  12. adoquery1.Open;



El problema es si yo kiero buscar la fecha desde a hasta segun la tengo guardada del mismo dia, no se muestra la consulta, segun vi el problema es que datetimepicker, estoy guardando la fecha y hora en lo registro, por tal razon no puedo ver la consulta de un dia.

Por favor aquien me puede ayuda, y si no entienden como describo, favor decirme.
  • 0

#2 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 posts
  • LocationEspaña

Posted 08 March 2012 - 02:24 AM

Buenas,

De hecho, si tu pones un between en un campo fecha-hora el mismo día pero sin poner las horas, es como si estuvieras poniendo "dd/mm/yyyy 00:00:00" en los dos fecha-hora, de ahí que no obtengas resultados

Tienes dos opciones para hacer lo que quieres, o bien poner la hora

'dd/mm/yyyy 00:00:00' and 'dd/mm/yyyy 23:59:59'

o bien, el segundo fecha-hora que sea un día más que el primero

'dd/mm/yyyy 00:00:00' and 'dd+1/mm/yyyy 00:00:00'

Espero te sirva

Nos leemos

  • 0

#3 Nikolas

Nikolas

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 604 posts
  • LocationMar del Plata / Bs As / Argentina

Posted 11 March 2012 - 11:16 AM

proba con:

adoquery1.Parameters.ParamByName('Desde').Value := Datetimepicker1.Date;
adoquery1.Parameters.ParamByName('Hasta').Value := Datetimepicker2.Date;


y si el motor, toma la fecha como MES/DIA/AÑO vas a tener que dar vuelta la fecha.

ahí te va a andar.  <:o)
  • 0

#4 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 11 March 2012 - 11:51 AM

Hola.

Otra opción : en el momento del filtro elimina las partes de hora de las fechas.

Es decir :

SELECT * FROM datos WHERE condicion = :Condicion AND cast(fecha as DATE) BETWEEN :Desde AND :Hasta


Salutacions.
  • 0

#5 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 posts
  • LocationEspaña

Posted 12 March 2012 - 02:32 AM

Buenas,

Nikolas: eso no te va a funcionar para campos TimeStamp por el motivo que he explicado anteriormente. Si no se especifica la hora, te tomará las 00:00:00.

Marc: la solución que das, si bien es válida, ten presente que dependiendo del motor que uses, si ese campo tiene un índice, no lo usará (al menos en Firebird). Por eso no incluí esta opción en la respuesta anterior ;) Es preferible hacer un poco de programación (sumarle 1 día al hasta es una simple instrucción en Delphi) y aprovechar el índice de la tabla para agilizar la consulta



delphi
  1. adoquery1.Parameters.ParamByName('Hasta').Value := IncDay(Datetimepicker2.DateTime);



Nos leemos

  • 0

#6 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 12 March 2012 - 03:33 AM

Hola Xavi.

Es que si le sumas 1 al día, entonces te va a aceptar unos pocos resultados inválidos (todos los que se hayan anotado al día siguiente, exactamente a las 00:00:00).

Es decir, si estamos buscando la lista de datos hasta el día 12 de marzo, también nos filtrará aceptando los datos del día 13 de marzo a las 00:00.

En este caso, la búsqueda debería ser mayor o igual que DESDE y estrictamente menor a HASTA + 1.


SELECT * FROM datos WHERE condicion = :Condicion AND fecha >= :Desde AND fecha < (:Hasta + 1)


NOTA: Por cierto, normalmente se puede añadir un índice para la expresión CAST(fecha as DATE), para agilizar por ese índice mi primera propuesta (aunque imagino que Access no soporta índices por expresiones, pero Firebird sí que permitirá optimizarla la consulta de esa forma).

Saludos.
  • 0

#7 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 posts
  • LocationEspaña

Posted 12 March 2012 - 08:28 AM

Buenas,

Es correcto lo que dices, Marc, el sumar 1 a la fecha "hasta" hará que los que hayan fichado antes de las 00:00:01 (es decir, en el primer segundo del día) se incluyan en esa sentencia. No obstante, y dependiendo del tipo de empresa para el que vaya destinado el programa de control horario, ese caso no se aplicaría dado que nadie ficharía en ese primer segundo del día :-)

En el caso de aplicarse, como bien dices, no se debería usar el between, sino un coparador de >= para la fecha-inicio y < para la fecha-fin

Como dices, en Firebird se podría "saltar" ese problemilla haciendo un índice con una expresión ;)

Ens llegin nen
  • 0

#8 vvalladolid

vvalladolid

    Advanced Member

  • Miembros
  • PipPipPip
  • 90 posts
  • LocationMéxico

Posted 12 March 2012 - 09:04 AM

Hola,

Hasta donde me dan mis pocos conocimientos tienes 2 problemas.

1.- El TDateTimePicker sólo te toma fecha u hora, no ambas.

Texto de la ayuda de delphi.

TDateTimePicker is a visual component designed specifically for entering dates or times. In dmComboBox date mode, it resembles a list box or combo box, except that the drop-down list is replaced with a calendar illustration; users can select a date from the calendar. Dates or times can also be selected by scrolling with Up and Down arrows and by typing.

Por lo que debes de armar tus campos de fecha inicial y final con ambos datos. Fecha y hora.

Si no te interesa que el usuario proporcione la hora, debes de armar tus fechas a mano con ambos campos fecha y hora. Pero debes considerar hasta los milesegundos ya que para comparación esto te afecta.

Si la intención es que el usuario proporcione toda la información, te recomiendo que pongas 2 TDateTimePicker, uno para fecha y otro para hora, tanto para fecha inicial como para fecha final.

Debes de usar las funciones EncodeDateTime y DecodeDateTime.

Puedes seguir estos ejemplos.

http://www.delphibas...=EncodeDateTime

http://www.delphibas...=DecodeDateTime


Ojala y soluciones tu problema.

Saludos,

  • 0




IP.Board spam blocked by CleanTalk.