2011-07-19 25 views
56

que tienen algo de SQL como esto:Oracle DateTime en Where Clause?

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE TIME_CREATED >= TO_DATE('26/JAN/2011','dd/mon/yyyy') 

-> Esto devuelve 10 filas y TIME_CREATED = '26-enero-2011'

Ahora cuando hago esto no consigo ningún filas más atrás,

SELECT EMP_NAME, DEPT 
    FROM EMPLOYEE 
    WHERE TIME_CREATED = TO_DATE('26/JAN/2011','dd/mon/yyyy') 

-> Tomó la mayor que fuera

algún motivo por qué?

+3

Debe evitar los formatos de fecha dependientes del idioma. Eso puede causar problemas en diferentes sistemas. Debería usar '01' en lugar de' JAN' (además del formato apropiado del curso) para asegurarse de que su código se ejecute sin problemas en cualquier sistema. –

Respuesta

108

Sí: TIME_CREATED contiene una fecha y un tiempo. TRUNC utilizar para despojar el tiempo:

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE TRUNC(TIME_CREATED) = TO_DATE('26/JAN/2011','dd/mon/yyyy') 

ACTUALIZACIÓN:
Como señala Dave Costa en el comentario anterior, esto evitará que Oracle de utilizar el índice de la columna TIME_CREATED si existe. Un enfoque alternativo sin este problema es el siguiente:

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE TIME_CREATED >= TO_DATE('26/JAN/2011','dd/mon/yyyy') 
     AND TIME_CREATED < TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1 
+13

Tenga en cuenta que este enfoque evitará el uso de un índice en TIME_CREATED, si existe. –

+0

@Dave: gracias por ese puntero. Actualicé mi respuesta. –

+0

Gracias publicando la solución. Fue rápido y fácil de encontrar. Mientras he trabajado en otros DBMS como Ingres, MS-SQL, MS-Access y DB2, no he trabajado con Oracle antes de mi asignación actual. –

6

Esto se debe a una columna DATE en Oracle también contiene una parte del tiempo. El resultado de la función to_date() es una fecha con el tiempo configurado en 00:00:00 y, por lo tanto, probablemente no coincida con ninguna fila de la tabla.

Deberá utilizar:

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE trunc(TIME_CREATED) = TO_DATE('26/JAN/2011','dd/mon/yyyy') 
3

Como otras personas han comentado anteriormente, utilizando TRUNCAR se impide la utilización de índices (si había un índice en TIME_CREATED). Para evitar ese problema, la consulta puede ser estructurada como

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE TIME_CREATED BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') 
      AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + INTERVAL '86399' second; 

86399 siendo 1 segundo menor que el número de segundos en un día.

15

También puede utilizar el siguiente para incluir la porción de tiempo en su consulta:

SELECT EMP_NAME 
    , DEPT 
    FROM EMPLOYEE 
WHERE TIME_CREATED >= TO_DATE('26/JAN/2011 00:00:00', 'dd/mon/yyyy HH24:MI:SS'); 
1

También puede hacer:

SELECT EMP_NAME, DEPT 
FROM EMPLOYEE 
WHERE TRUNC(TIME_CREATED) = DATE '2011-01-26' 
Cuestiones relacionadas