Oracle DateTime in Where Clause?


84

Mam sql coś takiego:

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

-> Zwraca 10 wierszy i TIME_CREATED = '26 -JAN-2011 '

Teraz, kiedy to robię, nie odzyskuję żadnych wierszy

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

-> Wziął większe niż na zewnątrz

Jakiś powód dlaczego?


4
Należy unikać formatów daty zależnych od języka. Może to powodować problemy w różnych systemach. Powinieneś użyć 01zamiast JAN(plus oczywiście odpowiedni format), aby upewnić się, że twój kod działa bez problemów w każdym systemie.
a_horse_with_no_name

Odpowiedzi:


149

Tak: TIME_CREATED zawiera datę i godzinę . Użyj, TRUNCaby usunąć czas:

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

AKTUALIZACJA:
Jak zauważa Dave Costa w poniższym komentarzu, uniemożliwi to Oracle korzystanie z indeksu kolumny, TIME_CREATEDjeśli istnieje. Alternatywnym podejściem bez tego problemu jest:

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
Zauważ, że to podejście uniemożliwi użycie indeksu w TIME_CREATED, jeśli taki istnieje.
Dave Costa,

Dziękuję za wysłanie rozwiązania. To było szybkie i łatwe do znalezienia. Chociaż pracowałem nad innymi systemami DBMS, takimi jak Ingres, MS-SQL, MS-Access i DB2, nie pracowałem z Oracle przed moim obecnym zadaniem.
Jason TEPOORTEN

Dlaczego nie używać BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1?
ajeh

2
@ajeh: Nie lubię z betweenpowodu niejednoznaczności. Brzmi to tak, jakby wyłączało granice, podczas gdy w rzeczywistości obejmuje. Dlatego tego unikam. Ponadto w tym konkretnym przykładzie nie byłoby to to samo.
Daniel Hilgarth,

28

Możesz również użyć następujących elementów, aby uwzględnić część CZAS w zapytaniu:

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


7

Dzieje się tak, ponieważ DATEkolumna w Oracle zawiera również część czasu. Wynikiem to_date()funkcji jest data z ustawioną godziną, 00:00:00dlatego prawdopodobnie nie pasuje ona do żadnych wierszy w tabeli.

Powinieneś użyć:

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

5

Jak skomentowały inne osoby powyżej, użycie TRUNC uniemożliwi użycie indeksów (jeśli indeks istniał na TIME_CREATED). Aby uniknąć tego problemu, zapytanie może mieć strukturę

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 to 1 sekunda mniej niż liczba sekund w ciągu dnia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.