Oracle DateTime în clauza Where? (Programare, Sql, Oracle, Timp, Data Aritmetică)

sanjeev40084 a intrebat.

Am sql ceva de genul acesta:

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

-> Aceasta returnează 10 rânduri și TIME_CREATED = ’26-JAN-2011′

Acum, când fac acest lucru, nu primesc niciun rând înapoi,

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

-> Am luat mai mare decât afară

Există vreun motiv pentru care?

Comentarii

  • Ar trebui să evitați formatele de date dependente de limbă. Acest lucru poate cauza probleme pe diferite sisteme. Ar trebui să folosiți 01 în loc de JAN (plus formatul corespunzător, bineînțeles) pentru a vă asigura că codul dvs. rulează fără probleme pe orice sistem. –  > Por un_calul_cu_nume_de_cabalâc.
5 răspunsuri
Daniel Hilgarth

Da: TIME_CREATED conține o dată și un câmp oră. Utilizați TRUNC pentru a elimina ora:

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

UPDATE:
După cum subliniază Dave Costa în comentariul de mai jos, acest lucru va împiedica Oracle să utilizeze indexul coloanei TIME_CREATED dacă acesta există. O abordare alternativă fără această problemă este următoarea:

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

Comentarii

    15

  • Rețineți că această abordare va împiedica utilizarea unui index pentru TIME_CREATED, dacă există unul. –  > Por Dave Costa.
  • Vă mulțumim că ați publicat soluția. A fost rapid și ușor de găsit. Deși am lucrat cu alte SGBD, cum ar fi Ingres, MS-SQL, MS-Access și DB2, nu am lucrat cu Oracle înainte de misiunea mea actuală. –  > Por Jason TEPOORTEN.
  • De ce să nu folosiți BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1? –  > Por ajeh.
  • @ajeh: Nu-mi place between din cauza ambiguității. Sună ca și cum ar fi exclusive limitele, când de fapt este inclusivă. De aceea o evit. În plus, în acest exemplu concret, nu ar fi același lucru. –  > Por Daniel Hilgarth.
davidsr

De asemenea, puteți utiliza următoarele pentru a include porțiunea TIME în interogare:

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

a_calul_cu_numele_de_câine

Acest lucru se datorează faptului că a DATE coloană din Oracle conține și o parte de timp. Rezultatul din to_date() este o dată cu ora setată la 00:00:00 și, prin urmare, probabil că nu se potrivește cu niciun rând din tabel.

Ar trebui să utilizați:

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

Matas Vaitkevicius

De asemenea, ați putea folosi:

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

Basanth Roy

După cum au comentat și alte persoane mai sus, utilizarea TRUNC va împiedica utilizarea indicilor (dacă a existat un indice pe TIME_CREATED). Pentru a evita această problemă, interogarea poate fi structurată astfel

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 fiind cu 1 secundă mai puțin decât numărul de secunde dintr-o zi.