web-dev-qa-db-fra.com

DateTime Oracle dans la clause Where?

J'ai quelque chose comme ça SQL:

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

-> Ceci retourne 10 lignes et TIME_CREATED = '26 -JAN-2011 '

Maintenant, quand je fais cela, je ne reçois plus de lignes,

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

-> a pris le plus de sort

Une raison pour laquelle?

72
sanjeev40084

Oui: TIME_CREATED contient une date et un heure. Utilisez TRUNC pour décaler le temps:

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

PDATE:
Comme le souligne Dave Costa dans le commentaire ci-dessous, cela empêchera Oracle d’utiliser l’index de la colonne TIME_CREATED s’il existe. Une approche alternative sans ce problème est la suivante:

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
132
Daniel Hilgarth

Vous pouvez également utiliser les éléments suivants pour inclure la partie TIME dans votre requête:

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

En effet, une colonne DATE dans Oracle contient également une partie heure. Le résultat de la fonction to_date() est une date dont l'heure est définie sur 00:00:00 et ne correspond donc probablement à aucune ligne de la table.

Tu devrais utiliser:

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

Comme d'autres personnes l'ont déjà mentionné, l'utilisation de TRUNC empêchera l'utilisation d'index (s'il y avait un index sur TIME_CREATED). Pour éviter ce problème, la requête peut être structurée de la manière suivante:

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 correspond à 1 seconde de moins que le nombre de secondes d'un jour.

4
Basanth Roy

Vous pouvez aussi faire:

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