Oracle SQL에서 날짜 비교


141

1994 년 6 월 20 일 이후에 고용 된 직원 수를 표시하려고하는데 "JUN"유효하지 않은 식별자라는 오류가 표시됩니다. 감사합니다!

Select employee_id, count(*)
From Employee
Where to_char(employee_date_hired, 'DD-MON-YY') > 31-DEC-95; 

1
당신이 중 하나를 사용할 수 있음을 유의하십시오 > <또는BETWEEN '' AND ''
— 앤드류

답변:


296

31-DEC-95문자열이 아니거나입니다 20-JUN-94. 그들은 끝에 여분의 물건이 추가 된 숫자입니다. 작은 따옴표 '31-DEC-95'또는 이어야합니다 . 이렇게하면 문자열 비교를 수행 할 수 있습니다.'20-JUN-94''

그러나 문자열 비교는 수행하지 않습니다. 당신은 날짜 비교를하고 있습니다. 문자열을 날짜로 변환해야합니다. 내장 TO_DATE()함수 또는 날짜 리터럴을 사용하십시오 .

TO_DATE ()

select employee_id
  from employee
 where employee_date_hired > to_date('31-DEC-95','DD-MON-YY')

이 방법에는 몇 가지 불필요한 함정이 있습니다

  • 의견에 언급 된 a_horse_with_no_name DEC이 반드시 12 월을 의미하는 것은 아닙니다. 귀하 NLS_DATE_LANGUAGE와 NLS_DATE_FORMAT설정 에 따라 다릅니다 . 모든 로케일에서 작업과 비교할 수 있도록 대신 날짜 시간 형식 모델을 사용할 수 있습니다.MM
  • '95 년은 정확하지 않습니다. 1995 년을 의미하지만 50 년이라면 1950 년 또는 2050 년은 무엇입니까? 항상 명시하는 것이 가장 좋습니다
select employee_id
  from employee
 where employee_date_hired > to_date('31-12-1995','DD-MM-YYYY')

날짜 리터럴

날짜 리터럴은 ANSI 표준의 일부이므로 Oracle 특정 기능을 사용할 필요가 없습니다. 리터럴을 사용할 때는 날짜 형식을 지정 해야YYYY-MM-DD 하며 시간 요소를 포함 할 수 없습니다.

select employee_id
  from employee
 where employee_date_hired > date '1995-12-31'

Oracle 날짜 데이터 유형에는 시간 단위가 포함되므로 시간 부분이없는 날짜는과 같습니다 1995-12-31 00:00:00.

시간 부분을 포함하려면 타임 스탬프 리터럴을 사용해야합니다. YYYY-MM-DD HH24:MI:SS[.FF0-9]

select employee_id
  from employee
 where employee_date_hired > timestamp '1995-12-31 12:31:02'

추가 정보

NLS_DATE_LANGUAGE에서 유래 NLS_LANGUAGE하고 NLS_DATE_FORMAT로부터 유도된다 NLS_TERRITORY. 데이터베이스를 처음 만들 때 설정되지만 실제로 필요한 경우에만 초기화 매개 변수 파일을 변경하거나 ALTER SESSION구문 을 사용하여 세션 수준에서 변경할 수 있습니다 . 예를 들어 :

alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';

이것은 다음을 의미합니다.

  • DD 월의 일, 1-31
  • MM 연도의 숫자 월, 01-12 (1 월은 01)
  • YYYY네 자리 연도-내 생각에 이것은 당신이 말하는 세기와 혼동이 없기 때문에 항상 2 자리 연도보다 낫습니다 YY.
  • HH24 하루 중 시간, 0-23
  • MI 분, 0-59
  • SS 분의 초, 0-59

쿼리하여 현재 언어 및 날짜 언어 설정을 확인하고 쿼리 V$NLS_PARAMETERSs하여 유효한 값의 전체 범위를 찾을 수 있습니다 V$NLS_VALID_VALUES.

추가 자료


또한 원하는 경우 다음 count(*)을 기준으로 그룹화해야합니다.employee_id

select employee_id, count(*)
  from employee
 where employee_date_hired > date '1995-12-31'
 group by employee_id

이렇게하면 수 있습니다 당을 employee_id .


13
to_date ()에서 형식 마스크를 사용하는 경우 +1 다른 언어 설정으로 인해 다른 환경에서는 여전히 실패 할 수 있습니다. DEC반드시 유효한 월일 필요는 없습니다. 일반적으로 이름 대신 숫자를 사용하는 것이 좋습니다
— a_horse_with_no_name

1
당신은 할 수 있습니다 은 ANSI 문자와 시간을 지정 - 당신은 단지 지정해야합니다 timestamp대신 리터 2 인 date문자 : timestamp '2015-01-30 19:42:04' (ANSI SQL의 경우 a 때문에 date데이터 유형이 시간이없는, 단지 timestamp데이터 유형 않습니다).
— a_horse_with_no_name

1
ANSI 날짜 리터럴은 매번 TO_DATE와 Date-Format을 입력해야하는 것을 비교하는 간결한 방법입니다. 좋은 게으른 나 같은 개발자. 주목해야 할 것은 실제로 DATE 2016-04-01수단 2016-04-01 00:00:00입니다. 그리고이 구문은 Oracle 9i 부터 ANSI-SQL 구문이 Oracle에 도입 된 곳에서 작동한다고 생각합니다 .
— LeOn-Han Li

1
내 생각은 지난 4 년 동안 크게 발전했습니다 @Leon :-) '나는 대답을 업데이트했습니다. 날짜 리터럴에는 시간 요소가 포함되어 있지 않지만 언급 한대로 이것을 명시 적으로 언급했습니다. 9i 확장 지원은 거의 6 년 전에 끝났으며 14 년 전에 릴리스되었습니다. 대다수의 사용자에게 더 이상 관련성이 없어야합니다.
— Ben


6

결론,

to_char 자체 방식으로 작동

그래서,

MM-DD-YY 또는 DD-MM-YYYY 또는 다른 형식 대신 항상이 형식 YYYY-MM-DD 를 사용하여 비교하십시오.


4

trunc 및 to_date를 다음과 같이 사용할 수 있습니다.

select TO_CHAR (g.FECHA, 'DD-MM-YYYY HH24:MI:SS') fecha_salida, g.NUMERO_GUIA, g.BOD_ORIGEN, g.TIPO_GUIA, dg.DOC_NUMERO, dg.* 
from ils_det_guia dg, ils_guia g
where dg.NUMERO_GUIA = g.NUMERO_GUIA and dg.TIPO_GUIA = g.TIPO_GUIA and dg.BOD_ORIGEN = g.BOD_ORIGEN
and dg.LAB_CODIGO = 56 
and trunc(g.FECHA) > to_date('01/02/15','DD/MM/YY')
order by g.FECHA;

2

귀하의 질문에서 :

Select employee_id, count(*) From Employee 
Where to_char(employee_date_hired, 'DD-MON-YY') > '31-DEC-95' 

1994 년 6 월 20 일 이후에 고용 된 직원 수를 표시하지 않는 것으로 생각합니다. 직원 수를 표시하려면 다음을 사용할 수 있습니다.

Select count(*) From Employee 
Where to_char(employee_date_hired, 'YYYMMMDDD') > 19940620 

사용 가능한 날짜를 비교하는 가장 좋은 방법은 다음과 같습니다.

employee_date_hired > TO_DATE('20-06-1994', 'DD-MM-YYYY');
or
to_char(employee_date_hired, 'YYYMMMDDD') > 19940620;

-4

날짜는 문자로 변환되므로 작은 따옴표가 있어야합니다.

employee_id를 선택하고 count (*)
직원으로부터
어디에 to_char (employee_date_hired, 'DD-MON-YY')> '31 -DEC-95 ';

1
이 SQL은 암시 적 날짜 형식을 사용하므로 항상 작동하지는 않습니다.
— Jon Heller

5
특정 NLS_ * 설정에서만 작동하며 다른 클라이언트 나 서버에서는 작동하지 않을 수 있습니다. 허용 된 답변은 왜 명시적인 날짜 형식이 중요한지를 설명합니다.
— Jon Heller

이 방법은 날짜가 아닌 문자열을 비교합니다. 두 번째 문자열은 "3"으로 시작하므로 비교는 "알파벳 순서"와 같이 작동합니다. 흥미롭게도,이 유형의 비교는 YYYY-MM-DD와 같은 형식을 사용하는 경우 실제로 실수로 정렬됩니다. 물론 날짜와 날짜를 비교하는 것이 좋습니다.
— Nick Perkins
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.