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_LANGUAGENLS_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.