PREGUNTA: ¿Por qué el SQL ENTRE es inclusivo?
RESPUESTA: Debido a que los diseñadores del lenguaje SQL tomaron una mala decisión de diseño, en el sentido de que no pudieron entregar una sintaxis que permitiera a los desarrolladores especificar cuál de las 4 variantes de ENTRE (cerrado, semiabierto a la izquierda, semiabierto a la derecha o abierto ) preferirían
RECOMENDACIÓN: A menos que / hasta que se modifique el estándar SQL, no use ENTRE las fechas / horas. En su lugar, adopte el hábito de codificar las comparaciones de rango DATE como condiciones independientes en los límites inicial y final de su rango ENTRE. Esto es un poco detallado, pero lo dejará escribiendo condiciones que son intuitivas (por lo tanto, menos propensas a tener errores) y claras para los optimizadores de la base de datos, lo que permite determinar planes de ejecución óptimos e índices que se utilizarán.
Por ejemplo, si su consulta acepta una especificación del día de entrada y debe devolver todos los registros que cayeron en esa fecha, codificaría como:
WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1
Tratar de escribir la lógica usando ENTRE arriesga problemas de rendimiento y / o código defectuoso. Tres pasos en falso comunes:
1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1
Esto es casi seguro que es un error: el usuario espera ver solo los registros de una fecha en particular, sin embargo, un día terminará con un informe que contiene registros de las 12:00 a.m. del día siguiente.
2) WHERE TRUNC(DATE_FIELD) = :dt
Da la respuesta correcta, pero la aplicación de la función a DATE_FIELD hará que la mayoría de las indexaciones / estadísticas sean inútiles (aunque a veces los DBA intentarán ayudar agregando índices basados en funciones a los campos de fecha, lo que aún consumirá horas hombre y espacio en disco y agregará gastos generales al DIU operaciones en la mesa)
3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60
Tom Kyte, extraordinario gurú de Oracle, recomienda esta solución poco elegante (IMO). Funciona muy bien hasta que pasa todo el día para encontrar ese "1-1 / 24/06/60" en una consulta que da resultados incompletos ... o hasta que lo use accidentalmente en un campo TIMESTAMP. Además, es un poco patentado; compatible con el tipo de datos DATE de Oracle (que sigue al segundo), pero debe ajustarse a la precisión DATE / TIME de diferentes productos de bases de datos.
SOLUCIÓN: Solicite al comité ANSI SQL que mejore las especificaciones del lenguaje SQL modificando la sintaxis ENTRE para admitir la especificación de alternativas al valor predeterminado CERRADO / INCLUSIVO. Algo así haría el truco:
expr1 ENTRE expr2 [ INCL [USIVE] | EXCL [USIVE]] y expr3 [ INCL [USIVE] | EXCLUSIVO] ]
Considere cuán fácil se vuelve expresar WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(o simplemente WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)
Tal vez ANSI SQL: 2015?