MySQL CAST —
형 변환(Casting) 완전 정리
날짜와 시간이 뒤섞인 문자열 하나를 CAST로 세 가지 다른 타입으로 변환해보는 코드다. 같은 원본 값에서 "날짜만", "시간만", "전체 다"를 각각 뽑아내는 원리를 살펴본다.
| 변환 타입 | CAST 결과 | 남는 정보 |
|---|---|---|
AS DATE |
2020-10-19 | 연-월-일만 |
AS TIME |
12:35:29 | 시:분:초만 |
AS DATETIME |
2020-10-19 12:35:29 | 날짜 + 시간 전체 |
DB 안에서 날짜·시간은 우리가 화면에서 보는 문자처럼 그대로 저장되지 않는다. MySQL은 DATE·TIME·DATETIME마다 내부적으로 다른 바이트 구조를 쓴다. 그런데 프로그램에서 넘어오는 값(폼 입력, 다른 시스템에서 온 문자열 등)은 대부분 텍스트다. 이 텍스트를 DB가 이해하는 날짜 타입으로 바꿔주는 다리 역할이 필요한데, 그게 CAST다.
또한 '2020-10-19 12:35:29.123'처럼 날짜+시간+밀리초가 한 문자열에 다 들어있을 때, 필요한 부분만 잘라서 쓰고 싶은 경우가 많다. 예를 들어 "가입일"만 보여주고 싶은데 원본은 정확한 타임스탬프 문자열인 상황이다.
CAST는 항상 같은 구조를 가진다. 괄호 안에 바꾸고 싶은 값, AS 키워드, 그리고 바꿀 타입 순서다. 값 자리에는 문자열 리터럴뿐 아니라 컬럼명, 다른 함수의 결과도 들어갈 수 있다.
- CAST 괄호 안의 AS → "이 타입으로 바꿔라"는 뜻 (필수)
- SELECT 문 뒤의 AS → 결과 컬럼에 별칭을 붙이는 것 (선택)
- 이번 코드의
AS 'DATE'는 후자 — 결과 컬럼 이름을 'DATE'로 정한 것뿐이다
CAST('2020-10-19 12:35:29.123' AS DATE)는 문자열 전체에서 연-월-일 부분만 읽어 DATE 타입 값으로 만든다. 뒤에 붙은 12:35:29.123은 반올림되는 게 아니라 그냥 버려진다.
23:59:59처럼 자정에 가까운 시간이어도 날짜가 다음날로 넘어가지 않는다. 문자열에 적힌 날짜 그대로만 남는다.
CAST('2020-10-19 12:35:29.123' AS TIME)는 반대로 시간 부분만 뽑아낸다. 결과는 12:35:29이며, 앞의 날짜 2020-10-19는 완전히 사라진다. 기본 TIME 타입은 밀리초 자릿수(fsp, fractional seconds precision)를 지정하지 않으면 소수점 이하를 버리기 때문에 .123도 함께 사라진다.
CAST('2020-10-19 12:35:29.123' AS DATETIME)은 날짜와 시간을 모두 살려 2020-10-19 12:35:29를 돌려준다. 다만 여기서도 .123(밀리초)은 사라진다. 기본 DATETIME도 fsp가 0이기 때문이다.
CAST(값 AS DATETIME(3))처럼 괄호 안에 정밀도 자릿수를 직접 지정해야 한다. 숫자 3은 소수점 이하 3자리(밀리초 단위)까지 저장하겠다는 뜻이다.MySQL은 'YYYY-MM-DD', 'YYYY-MM-DD HH:MM:SS' 같은 표준에 가까운 형식의 문자열을 만나면 각 자리를 연·월·일·시·분·초로 나눠 해석한다. 구분자로 하이픈(-)뿐 아니라 슬래시(/)나 점(.)도 인식하지만, 순서(연-월-일)가 바뀌면 제대로 해석하지 못하거나 엉뚱한 값이 나올 수 있다.
NULL·경고를 반환할 수 있다. 되도록 'YYYY-MM-DD HH:MM:SS' 형식을 지키는 것이 안전하다.MySQL에는 CAST 말고 CONVERT라는 형변환 함수도 있다. 표준 SQL(ANSI SQL)에서 온 CAST와 달리 CONVERT는 MySQL을 포함한 일부 DB에서 지원하는 방식이며, 문자셋(캐릭터셋) 변환까지 처리할 수 있다는 점이 다르다.
CAST(값 AS 타입)타입 지정에
AS 사용여러 DB(Oracle, PostgreSQL 등)에서도 호환
CONVERT(값, 타입)타입 지정에 콤마(,) 사용
CONVERT(값 USING 문자셋)도 가능MySQL은 타입이 안 맞아도 최대한 알아서 맞춰 계산해준다. 예를 들어 문자열 컬럼과 숫자를 비교하면 MySQL이 문자열을 숫자로 암시적으로 바꿔서 비교한다. 편리해 보이지만 두 가지 함정이 있다.
| 상황 | 암시적 변환 결과 | 문제점 |
|---|---|---|
WHERE 문자열컬럼 = 123 |
컬럼 값을 숫자로 변환 후 비교 | 인덱스를 못 타 조회 속도 저하 |
'10' + '20' |
문자열을 숫자로 바꿔 30 계산 | 문자열 연결(concat)로 착각하기 쉬움 |
CAST(123 AS CHAR) |
숫자를 문자 '123'으로 명시 변환 | 정상 — 의도가 코드에 드러나 안전 |
CAST(값 AS CHAR), 문자를 숫자로 바꿀 땐 CAST(값 AS SIGNED) 또는 UNSIGNED를 쓴다. 암시적 변환에 기대지 않고 항상 명시적으로 쓰는 습관이 실수를 줄인다.| 실수 | 증상 | 해결 |
|---|---|---|
| 표준과 다른 날짜 형식 문자열을 CAST | 결과가 NULL이거나 경고 발생 | 'YYYY-MM-DD HH:MM:SS' 형식으로 통일 |
| DATETIME으로 바꾸면 밀리초도 남을 거라 기대 | .123이 사라짐 | DATETIME(3)처럼 fsp(정밀도) 직접 지정 |
| TIME 타입에 24시간 넘는 기간을 기대 | 예상과 다른 값 발생 | TIME은 -838:59:59~838:59:59 범위임을 확인 |
CONVERT를 CAST처럼 CONVERT(값 AS 타입)로 작성 |
문법 오류 | CAST는 AS, CONVERT는 콤마(,) 사용 |
| 문자열 컬럼과 숫자를 그냥 비교 | 암시적 변환으로 인덱스 미사용, 속도 저하 | 타입을 미리 맞추거나 명시적 CAST 사용 |
| AS를 별칭용인지 타입지정용인지 혼동 | 구문 오류 또는 의도치 않은 결과 | CAST 괄호 안 AS=타입, SELECT 뒤 AS=별칭으로 구분 |
핵심 한 줄 요약
Tags
'php' 카테고리의 다른 글
| MySQL SET 변수 · PREPARE — 동적 쿼리 완전 정리 (0) | 2026.06.27 |
|---|---|
| MySQL CTE WITH — 공통 테이블 식 완전 정리 (0) | 2026.06.27 |
| MySQL 기초 — CREATE DATABASE · USE · SELECT · SHOW 완전 정리 (0) | 2026.06.27 |
| 시즌2 7편 — 이제, 그 'AI 부서'를 직접 만들어 봅시다 (0) | 2026.06.27 |
| 시즌2 8편 — GitHub이 뭔지부터, 머지 한 번에 자동 배포까지 (0) | 2026.06.27 |
왕진 블로그

댓글