MySQL EXTRACT() 함수에 날짜 값만 제공하면 어떻게 될까?
MySQL의 EXTRACT() 함수는 날짜·시간 값에서 연도, 월, 일, 시, 분, 초 등 원하는 단위를 추출하는 데 사용됩니다. 그렇다면 시간 정보가 전혀 없는 순수한 날짜 값(예: '2017-10-20')에 대해 시간 단위인 HOUR, MINUTE, SECOND를 추출하면 어떤 결과가 나올까요?
결론부터 말씀드리면, MySQL은 에러를 반환하지 않습니다. 대신 경고(Warning)와 함께 예상과 다른 값을 돌려줍니다. 아래 예제를 통해 하나씩 확인해 보겠습니다.
1. 날짜 값에서 HOUR(시) 추출하기
날짜 '2017-10-20'에서 시간(Hour)을 추출하면 결과는 0이며, 경고가 함께 발생합니다.
mysql> Select EXTRACT(Hour from '2017-10-20'); +---------------------------------+ | EXTRACT(Hour from '2017-10-20') | +---------------------------------+ | 0 | +---------------------------------+ 1 row in set, 1 warning (0.00 sec)
SHOW WARNINGS;로 경고 내용을 살펴보면 다음과 같습니다.
+---------+------+----------------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------------+ | Warning | 1292 | Truncated incorrect time value: '2017-10-20' | +---------+------+----------------------------------------------+ 1 row in set (0.00 sec)
경고 코드 1292는 "잘못된 시간 값이 잘렸다(Truncated incorrect time value)"는 의미입니다. 즉, MySQL은 '2017-10-20'을 온전한 시간 값으로 해석할 수 없기 때문에 불필요한 부분을 잘라낸 뒤 처리합니다.
2. 날짜 값에서 MINUTE(분) 추출하기
같은 날짜 값에서 분(Minute)을 추출하면 이번에는 20이라는 값이 반환되며, 역시 동일한 경고가 발생합니다.
mysql> Select EXTRACT(Minute from '2017-10-20'); +-----------------------------------+ | EXTRACT(Minute from '2017-10-20') | +-----------------------------------+ | 20 | +-----------------------------------+ 1 row in set, 1 warning (0.00 sec)
3. 날짜 값에서 SECOND(초) 추출하기
초(Second)를 추출하면 17이 반환되고, 마찬가지로 경고가 출력됩니다.
mysql> Select Extract(Second from '2017-10-20'); +-----------------------------------+ | Extract(Second from '2017-10-20') | +-----------------------------------+ | 17 | +-----------------------------------+ 1 row in set, 1 warning (0.00 sec)
왜 이런 결과가 나올까?
MySQL은 시간 부분이 없는 날짜 문자열을 시간 값으로 변환할 때, 잘못된 부분을 잘라내고 남은 숫자('2017')를 시간 표기로 해석합니다. 이 숫자는 00시 20분 17초(00:20:17)로 읽히기 때문에 HOUR는 0, MINUTE는 20, SECOND는 17이라는 결과가 나오는 것입니다.
정리하면 다음과 같습니다.
- HOUR → 0
- MINUTE → 20
- SECOND → 17
- 세 경우 모두 경고 코드 1292("Truncated incorrect time value") 발생
CURDATE()를 사용해도 같은 결과
현재 날짜를 반환하는 CURDATE() 함수를 사용해 시간 값(시, 분, 초)을 추출해도 위와 동일한 결과와 경고를 얻게 됩니다. CURDATE() 역시 시간 정보가 없는 순수한 날짜 값만 반환하기 때문입니다.
따라서 실무에서는 시간 단위를 추출할 때 반드시 DATETIME이나 TIME 타입처럼 시간 정보를 포함하는 값을 사용해야 하며, 순수한 DATE 값에 시간 추출을 시도하는 일이 없도록 주의하는 것이 좋습니다.