Manual de campo · trampas de SQL
BETWEEN 'a' AND 'b' sobre un TIMESTAMP convierte 'b' en 'b 00:00:00'. Todo lo que pasó después de la medianoche de ese día queda fuera, aunque el día entero debía contarse.
Cualquier filtro de fechas con BETWEEN sobre una columna TIMESTAMP (no DATE). Es la razón por la que 'del 1 al 30' casi nunca incluye el 30 entero.
Mal: BETWEEN corta el día 30 a la medianoche
SELECT tarjeta, entrada
FROM accesos
WHERE entrada BETWEEN '2026-09-01' AND '2026-09-30';
-- '2026-09-30' se interpreta como '2026-09-30 00:00:00':
-- la entrada de las 22:47 de ese mismo día queda fuera
Bien: rango semiabierto, sin adivinar la hora de corte
SELECT tarjeta, entrada
FROM accesos
WHERE entrada >= '2026-09-01'
AND entrada < '2026-10-01';
BETWEEN a AND b sobre un TIMESTAMP no es 'del día a al día b': es 'del instante a al instante b', y un literal de sólo fecha como '2026-09-30' se convierte en '2026-09-30 00:00:00'. Eso deja fuera las 23 horas y 59 minutos que le siguen, justo donde ocurrió el robo de esta pista. El rango semiabierto >= inicio AND < fin_exclusivo no tiene ese problema porque nunca depende de adivinar a qué hora empieza el día siguiente: basta con poner el primer instante que ya NO cuenta. La misma regla vale para meses y años: < '2026-10-01' incluye todo septiembre completo, sin importar la hora.
Esta trampa está escondida en un caso de verdad, con datos de verdad.
Jugar el caso 1 gratis →