Oracle DateTime in Where Clause?


84

Ho sql qualcosa del genere:

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

-> Restituisce 10 righe e TIME_CREATED = '26 -JAN-2011 '

Ora quando lo faccio non ricevo nessuna riga indietro,

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

-> Ha preso il maggiore che fuori

Qualche motivo per cui?


4
È necessario evitare formati di data dipendenti dalla lingua. Ciò può causare problemi su sistemi diversi. Dovresti usare 01invece di JAN(più il formato appropriato ovviamente) per assicurarti che il tuo codice funzioni senza problemi su qualsiasi sistema.
a_horse_with_no_name

Risposte:


149

Sì: TIME_CREATED contiene una data e un'ora . Usa TRUNCper togliere il tempo:

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

AGGIORNAMENTO:
come sottolinea Dave Costa nel commento qui sotto, questo impedirà a Oracle di utilizzare l'indice della colonna TIME_CREATEDse esiste. Un approccio alternativo senza questo problema è questo:

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

14
Nota che questo approccio impedirà l'uso di un indice su TIME_CREATED, se ne esiste uno.
Dave Costa

Grazie per aver postato la soluzione. È stato facile e veloce da trovare. Sebbene abbia lavorato su altri DBMS come Ingres, MS-SQL, MS-Access e DB2, non ho lavorato con Oracle prima del mio attuale incarico.
Jason TEPOORTEN

Perché non utilizzare BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1?
ajeh

2
@ajeh: non mi piace a betweencausa dell'ambiguità. Sembra che sia esclusivo dei limiti quando in realtà è inclusivo. Ecco perché lo evito. Inoltre, in questo esempio concreto, non sarebbe lo stesso.
Daniel Hilgarth

28

Puoi anche utilizzare quanto segue per includere la parte TIME nella tua query:

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

8

Potresti anche fare:

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

7

Questo perché una DATEcolonna in Oracle contiene anche una parte temporale. Il risultato della to_date()funzione è una data con l'ora impostata su00:00:00 e quindi probabilmente non corrisponde a nessuna riga nella tabella.

Dovresti usare:

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

5

Come altre persone hanno commentato sopra, l'uso di TRUNC impedirà l'uso degli indici (se c'era un indice su TIME_CREATED). Per evitare questo problema, la query può essere strutturata come

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 è 1 secondo inferiore al numero di secondi in un giorno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.