Where 절의 Oracle DateTime?


84

다음과 같은 SQL이 있습니다.

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

-> 이것은 10 개의 행을 반환하고 TIME_CREATED = '26 -JAN-2011 '

이제 내가 이것을 할 때 나는 어떤 행도 다시 얻지 못합니다.

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

-> 아웃보다 더 큰 걸

이유는 무엇입니까?


4
언어에 따른 날짜 형식은 피해야합니다. 그것은 다른 시스템에서 문제를 일으킬 수 있습니다. 당신은 사용해야하는 01대신 JAN모든 시스템에서 문제없이 확인 코드 실행을 만들기 위해 (물론 플러스 생성하라 형식).
a_horse_with_no_name

답변:


149

예 : TIME_CREATED에는 날짜와 시간이 포함 됩니다. 사용 TRUNC시간을 제거하기 위해 :

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

업데이트 :
Dave Costa가 아래 주석에서 지적했듯이, 이것은 Oracle이 TIME_CREATED존재하는 경우 열의 인덱스를 사용하는 것을 방지 합니다. 이 문제가없는 대안은 다음과 같습니다.

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
이 방법은 TIME_CREATED에 인덱스가있는 경우 사용하지 못하도록합니다.
Dave Costa

솔루션을 게시 해 주셔서 감사합니다. 빠르고 쉽게 찾을 수있었습니다. Ingres, MS-SQL, MS-Access 및 DB2와 같은 다른 DBMS에서 작업했지만 현재 작업 전에 Oracle과 함께 작업 한 적이 없습니다.
Jason TEPOORTEN

왜 사용하지 BETWEEN TO_DATE('26/JAN/2011','dd/mon/yyyy') AND TO_DATE('26/JAN/2011','dd/mon/yyyy') + 1않습니까?
ajeh

2
@ajeh : between모호함 때문에 좋아하지 않습니다 . 실제로 그것이 포괄적 일 때 경계가 배타적 인 것처럼 들립니다. 그것이 내가 그것을 피하는 이유입니다. 또한이 구체적인 예에서는 동일하지 않습니다.
Daniel Hilgarth

28

다음을 사용하여 쿼리에 TIME 부분을 포함 할 수도 있습니다.

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

8

다음을 수행 할 수도 있습니다.

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

7

이는 DATEOracle 의 열에도 시간 부분이 포함되어 있기 때문 입니다. to_date()함수 의 결과는 시간이로 설정된 날짜 00:00:00이므로 테이블의 어떤 행과도 일치하지 않을 수 있습니다.

다음을 사용해야합니다.

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

5

다른 사람들이 위에서 언급했듯이 TRUNC를 사용하면 인덱스 사용이 방지됩니다 (TIME_CREATED에 인덱스가있는 경우). 이러한 문제를 방지하기 위해 쿼리를 다음과 같이 구성 할 수 있습니다.

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 초 적습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.