데이터베이스 작업을 하다 보면 숫자를 문자로, 문자를 날짜로 변환해야 하는 상황이 끊임없이 발생합니다. “주문 번호를 문자열과 합쳐서 표시하고 싶은데”, “문자열로 저장된 날짜를 실제 날짜 타입으로 변환하려면?” – 이런 고민을 해결하는 것이 바로 타입 변환입니다. 오늘은 MSSQL의 두 가지 타입 변환 함수 CONVERT와 CAST의 모든 것을 실전 예제와 함께 완벽하게 정리해드립니다.
타입 변환이 왜 필요한가?
실무에서 데이터 타입 불일치는 매우 흔한 문제입니다:
- 외부 시스템에서 받은 날짜가 문자열로 저장됨
- 숫자 계산 결과를 문자열과 합쳐서 출력해야 함
- 서로 다른 타입의 컬럼을 비교해야 함
- 보고서에서 날짜 형식을 원하는 대로 표시해야 함
이런 상황에서 CONVERT와 CAST가 핵심 역할을 합니다.
CAST 함수: ANSI 표준 방식
CAST 기본 문법
CAST(표현식 AS 데이터타입 [(길이)])
CAST는 SQL 표준 함수로, 다양한 데이터베이스에서 호환되는 장점이 있습니다.
기본 사용 예제
-- 숫자를 문자로 변환
SELECT CAST(12345 AS VARCHAR(10)) AS 문자변환결과;
-- 결과: '12345'
-- 문자를 숫자로 변환
SELECT CAST('100' AS INT) AS 숫자변환결과;
-- 결과: 100
-- 문자를 날짜로 변환
SELECT CAST('2025-10-04' AS DATE) AS 날짜변환결과;
-- 결과: 2025-10-04
-- 실수를 정수로 변환 (소수점 버림)
SELECT CAST(123.456 AS INT) AS 정수변환결과;
-- 결과: 123
실전 예제 1: 문자열 결합
-- 주문 정보를 하나의 문자열로 결합
SELECT
'주문번호: ' + CAST(OrderID AS VARCHAR(10)) +
', 수량: ' + CAST(Quantity AS VARCHAR(10)) +
', 가격: ' + CAST(Price AS VARCHAR(20)) AS 주문정보
FROM Orders
WHERE OrderID = 1001;
실행 결과:
주문정보
------------------------------------------------
주문번호: 1001, 수량: 5, 가격: 25000
실전 예제 2: 날짜 비교
-- 문자열로 저장된 날짜를 실제 날짜로 변환하여 비교
SELECT
ProductName,
ExpireDate
FROM Products
WHERE CAST(ExpireDate AS DATE) < GETDATE()
AND CAST(ExpireDate AS DATE) >= DATEADD(DAY, -30, GETDATE());
이 쿼리는 최근 30일 이내에 유통기한이 지난 제품을 찾습니다.
CONVERT 함수: MSSQL 전용 강력한 기능
CONVERT 기본 문법
CONVERT(데이터타입 [(길이)], 표현식 [, 스타일])
CONVERT는 MSSQL 전용 함수로, 날짜/시간 형식 지정이 가능한 강력한 기능을 제공합니다.
기본 사용 예제
-- 숫자를 문자로 변환
SELECT CONVERT(VARCHAR(10), 12345) AS 문자변환결과;
-- 결과: '12345'
-- 날짜를 문자로 변환 (기본 형식)
SELECT CONVERT(VARCHAR(20), GETDATE()) AS 날짜문자변환;
-- 결과: 'Oct 4 2025 3:45PM'
-- 날짜를 문자로 변환 (스타일 지정)
SELECT CONVERT(VARCHAR(10), GETDATE(), 23) AS YYYY_MM_DD형식;
-- 결과: '2025-10-04'
CONVERT 날짜 스타일 코드 완벽 정리
주요 날짜 형식 스타일
| 스타일 | 출력 형식 | 예시 |
|---|---|---|
| 0 또는 100 | mon dd yyyy hh:miAM/PM | Oct 4 2025 3:45PM |
| 1 또는 101 | mm/dd/yyyy | 10/04/2025 |
| 2 또는 102 | yyyy.mm.dd | 2025.10.04 |
| 3 또는 103 | dd/mm/yyyy | 04/10/2025 |
| 4 또는 104 | dd.mm.yyyy | 04.10.2025 |
| 8 또는 108 | hh:mi:ss | 15:45:30 |
| 10 또는 110 | mm-dd-yyyy | 10-04-2025 |
| 11 또는 111 | yyyy/mm/dd | 2025/10/04 |
| 12 또는 112 | yyyymmdd | 20251004 |
| 20 또는 120 | yyyy-mm-dd hh:mi:ss | 2025-10-04 15:45:30 |
| 23 또는 121 | yyyy-mm-dd hh:mi:ss.mmm | 2025-10-04 15:45:30.123 |
실전 날짜 변환 예제
-- 현재 날짜/시간을 다양한 형식으로 변환
DECLARE @Now DATETIME = GETDATE();
SELECT
CONVERT(VARCHAR(30), @Now, 0) AS 기본형식,
CONVERT(VARCHAR(10), @Now, 1) AS 미국형식,
CONVERT(VARCHAR(10), @Now, 3) AS 영국형식,
CONVERT(VARCHAR(10), @Now, 11) AS ISO형식,
CONVERT(VARCHAR(8), @Now, 12) AS 숫자형식,
CONVERT(VARCHAR(8), @Now, 108) AS 시간만,
CONVERT(VARCHAR(23), @Now, 121) AS 밀리초포함;
실행 결과:
기본형식 미국형식 영국형식 ISO형식 숫자형식 시간만 밀리초포함
Oct 4 2025 3:45PM 10/04/2025 04/10/2025 2025/10/04 20251004 15:45:30 2025-10-04 15:45:30.123
CAST vs CONVERT: 어떤 것을 사용할까?
비교표
| 특징 | CAST | CONVERT |
|---|---|---|
| 표준 호환성 | ✅ ANSI SQL 표준 | ❌ MSSQL 전용 |
| 다른 DB 이식성 | ✅ 높음 (Oracle, MySQL 등) | ❌ 낮음 (MSSQL만) |
| 날짜 형식 지정 | ❌ 불가능 | ✅ 가능 (스타일 코드) |
| 문법 직관성 | ✅ 더 직관적 | ⚠️ 매개변수 순서 주의 |
| 성능 | 동일 | 동일 |
사용 권장 사항
CAST를 사용하세요:
- 다른 데이터베이스로 이식 가능성이 있을 때
- 단순한 타입 변환만 필요할 때
- SQL 표준을 준수하고 싶을 때
-- CAST 권장 사례
SELECT
CAST(Price AS DECIMAL(10,2)) AS 가격,
CAST(Quantity AS INT) AS 수량
FROM OrderDetails;
CONVERT를 사용하세요:
- 날짜/시간을 특정 형식으로 표시해야 할 때
- MSSQL에서만 사용할 것이 확실할 때
- 레거시 코드와의 일관성을 유지해야 할 때
-- CONVERT 권장 사례
SELECT
OrderDate,
CONVERT(VARCHAR(10), OrderDate, 23) AS 주문일자,
CONVERT(VARCHAR(8), OrderDate, 108) AS 주문시간
FROM Orders;
실무 활용 패턴
패턴 1: 보고서 날짜 형식 통일
-- 다양한 날짜 컬럼을 일관된 형식으로 표시
SELECT
OrderID,
CONVERT(VARCHAR(10), OrderDate, 23) AS 주문일,
CONVERT(VARCHAR(10), ShipDate, 23) AS 배송일,
CONVERT(VARCHAR(10), DeliveryDate, 23) AS 도착일,
DATEDIFF(DAY, OrderDate, DeliveryDate) AS 배송소요일수
FROM Orders
WHERE OrderDate >= '2025-01-01'
ORDER BY OrderDate DESC;
패턴 2: 동적 쿼리 생성
-- 검색 조건을 문자열로 결합
DECLARE @ProductID INT = 1001;
DECLARE @CategoryName VARCHAR(50) = '전자제품';
SELECT
'상품 ID ' + CAST(@ProductID AS VARCHAR(10)) +
'은(는) ' + @CategoryName + ' 카테고리에 속합니다.' AS 상품정보;
실행 결과:
상품정보
------------------------------------------------
상품 ID 1001은(는) 전자제품 카테고리에 속합니다.
패턴 3: 데이터 정제 (ETL)
-- 문자열로 저장된 잘못된 데이터를 정리
SELECT
ProductID,
ProductName,
-- 문자열 가격을 숫자로 변환 (에러 발생 시 NULL)
TRY_CAST(Price AS DECIMAL(10,2)) AS CleanedPrice,
-- 문자열 날짜를 날짜 타입으로 변환
TRY_CONVERT(DATE, RegisterDate, 23) AS CleanedDate
FROM RawProducts
WHERE TRY_CAST(Price AS DECIMAL(10,2)) IS NOT NULL;
패턴 4: 데이터 유효성 검증
-- 변환 가능한 데이터만 필터링
SELECT
CustomerID,
PhoneNumber,
Email,
BirthDate
FROM Customers
WHERE
-- 생년월일이 올바른 날짜 형식인지 확인
TRY_CONVERT(DATE, BirthDate) IS NOT NULL
-- 전화번호가 숫자로 변환 가능한지 확인
AND TRY_CAST(REPLACE(PhoneNumber, '-', '') AS BIGINT) IS NOT NULL;
고급 타입 변환 기법
TRY_CAST와 TRY_CONVERT: 안전한 변환
SQL Server 2012 이상에서는 변환 실패 시 에러 대신 NULL을 반환하는 안전한 함수를 제공합니다.
-- 일반 CAST: 변환 실패 시 에러 발생
SELECT CAST('abc' AS INT); -- 에러!
-- TRY_CAST: 변환 실패 시 NULL 반환
SELECT TRY_CAST('abc' AS INT) AS 결과; -- NULL
-- 실전 활용: 잘못된 데이터 필터링
SELECT
ProductID,
Price AS 원본가격,
TRY_CAST(Price AS DECIMAL(10,2)) AS 정제된가격,
CASE
WHEN TRY_CAST(Price AS DECIMAL(10,2)) IS NULL
THEN '변환 실패'
ELSE '정상'
END AS 상태
FROM Products;
실전 예제 3: 안전한 데이터 마이그레이션
-- 레거시 테이블에서 새 테이블로 데이터 이전
INSERT INTO NewProducts (ProductID, Name, Price, RegisterDate)
SELECT
ProductID,
ProductName,
-- 변환 실패 시 기본값 0 사용
ISNULL(TRY_CAST(Price AS DECIMAL(10,2)), 0) AS Price,
-- 변환 실패 시 현재 날짜 사용
ISNULL(TRY_CONVERT(DATE, RegisterDate, 23), GETDATE()) AS RegisterDate
FROM LegacyProducts
WHERE TRY_CAST(Price AS DECIMAL(10,2)) IS NOT NULL -- 가격이 유효한 것만
OR Price IS NULL; -- 또는 NULL인 경우
주요 데이터 타입 변환 예제
숫자 타입 변환
-- INT ↔ DECIMAL
SELECT
CAST(100 AS DECIMAL(10,2)) AS INT를DECIMAL로, -- 100.00
CAST(123.456 AS INT) AS DECIMAL을INT로, -- 123 (소수점 버림)
CAST(123.456 AS DECIMAL(5,1)) AS 반올림; -- 123.5
-- FLOAT ↔ VARCHAR
SELECT
CAST(123.456789 AS VARCHAR(20)) AS FLOAT를문자로,
CAST('123.456' AS FLOAT) AS 문자를FLOAT로;
-- 통화 형식 변환
SELECT
Price AS 원본,
CONVERT(VARCHAR(20), CAST(Price AS MONEY), 1) AS 통화형식
FROM Products;
문자열 타입 변환
-- VARCHAR ↔ NVARCHAR (유니코드)
SELECT
CAST('한글' AS NVARCHAR(10)) AS 유니코드변환,
CAST(N'Unicode' AS VARCHAR(10)) AS VARCHAR변환;
-- CHAR ↔ VARCHAR (공백 제거)
SELECT
CAST(' hello ' AS CHAR(10)) AS CHAR형, -- 고정 길이
CAST(' hello ' AS VARCHAR(10)) AS VARCHAR형; -- 가변 길이
-- 대소문자 변환과 함께
SELECT
UPPER(CAST(ProductCode AS VARCHAR(20))) AS 대문자코드
FROM Products;
날짜/시간 타입 변환
-- DATE, DATETIME, DATETIME2 변환
DECLARE @Now DATETIME2 = SYSDATETIME();
SELECT
CAST(@Now AS DATE) AS 날짜만,
CAST(@Now AS TIME) AS 시간만,
CAST(@Now AS DATETIME) AS DATETIME형식,
CAST(@Now AS VARCHAR(30)) AS 문자열형식;
-- 문자열을 날짜로 변환 (다양한 형식 지원)
SELECT
CONVERT(DATE, '2025-10-04', 23) AS ISO형식,
CONVERT(DATE, '10/04/2025', 101) AS 미국형식,
CONVERT(DATE, '04/10/2025', 103) AS 영국형식,
CONVERT(DATE, '20251004', 112) AS 숫자형식;
실전 복합 예제
예제 4: 판매 리포트 생성
-- 월별 판매 요약 리포트
SELECT
CONVERT(VARCHAR(7), OrderDate, 23) AS 년월, -- 2025-10
COUNT(*) AS 주문건수,
CAST(SUM(TotalAmount) AS DECIMAL(15,2)) AS 총판매액,
CAST(AVG(TotalAmount) AS DECIMAL(10,2)) AS 평균주문금액,
CAST(MIN(TotalAmount) AS DECIMAL(10,2)) AS 최소주문금액,
CAST(MAX(TotalAmount) AS DECIMAL(10,2)) AS 최대주문금액,
-- 텍스트 요약
'이번 달 주문 ' + CAST(COUNT(*) AS VARCHAR(10)) +
'건, 총 ' + CONVERT(VARCHAR(20), CAST(SUM(TotalAmount) AS MONEY), 1) +
'원 판매' AS 요약
FROM Orders
WHERE OrderDate >= DATEADD(MONTH, -6, GETDATE())
GROUP BY CONVERT(VARCHAR(7), OrderDate, 23)
ORDER BY 년월 DESC;
실행 결과:
년월 주문건수 총판매액 평균주문금액 최소주문금액 최대주문금액 요약
2025-10 125 15,234,500.00 121,876.00 10,000.00 500,000.00 이번 달 주문 125건, 총 15,234,500.00원 판매
2025-09 142 18,567,300.00 130,756.34 15,000.00 750,000.00 이번 달 주문 142건, 총 18,567,300.00원 판매
예제 5: 고객 나이 계산 및 그룹화
-- 생년월일로부터 나이 계산
SELECT
CustomerID,
CustomerName,
BirthDate,
CONVERT(VARCHAR(10), BirthDate, 23) AS 생년월일,
-- 나이 계산
DATEDIFF(YEAR, CAST(BirthDate AS DATE), GETDATE()) AS 만나이,
-- 연령대 그룹화
CASE
WHEN DATEDIFF(YEAR, CAST(BirthDate AS DATE), GETDATE()) < 20 THEN '10대'
WHEN DATEDIFF(YEAR, CAST(BirthDate AS DATE), GETDATE()) < 30 THEN '20대'
WHEN DATEDIFF(YEAR, CAST(BirthDate AS DATE), GETDATE()) < 40 THEN '30대'
WHEN DATEDIFF(YEAR, CAST(BirthDate AS DATE), GETDATE()) < 50 THEN '40대'
ELSE '50대 이상'
END AS 연령대
FROM Customers
WHERE TRY_CONVERT(DATE, BirthDate) IS NOT NULL
ORDER BY BirthDate;
예제 6: JSON 데이터 파싱
-- JSON 문자열에서 데이터 추출 및 타입 변환
DECLARE @json NVARCHAR(MAX) = N'{
"orderId": "1001",
"orderDate": "2025-10-04",
"amount": "125000",
"quantity": "5"
}';
SELECT
CAST(JSON_VALUE(@json, '$.orderId') AS INT) AS 주문번호,
CONVERT(DATE, JSON_VALUE(@json, '$.orderDate'), 23) AS 주문일자,
CAST(JSON_VALUE(@json, '$.amount') AS DECIMAL(10,2)) AS 금액,
CAST(JSON_VALUE(@json, '$.quantity') AS INT) AS 수량;
성능 고려사항
암시적 변환 vs 명시적 변환
-- ❌ 나쁜 예: 암시적 변환 (인덱스 사용 불가)
SELECT * FROM Orders
WHERE OrderID = '1001'; -- 문자열을 숫자 컬럼과 비교
-- ✅ 좋은 예: 명시적 변환 (인덱스 사용 가능)
SELECT * FROM Orders
WHERE OrderID = CAST('1001' AS INT);
-- 또는 애초에 올바른 타입 사용
SELECT * FROM Orders
WHERE OrderID = 1001;
인덱스 컬럼 변환 주의
-- ❌ 나쁜 예: 인덱스 컬럼을 변환하면 인덱스 사용 불가
SELECT * FROM Orders
WHERE CONVERT(VARCHAR(10), OrderDate, 23) = '2025-10-04';
-- ✅ 좋은 예: 비교값을 변환하여 인덱스 활용
SELECT * FROM Orders
WHERE OrderDate >= CONVERT(DATE, '2025-10-04', 23)
AND OrderDate < DATEADD(DAY, 1, CONVERT(DATE, '2025-10-04', 23));
일반적인 오류와 해결방법
오류 1: 변환 실패
-- 오류 발생
SELECT CAST('abc' AS INT);
-- Msg 245: Conversion failed when converting the varchar value 'abc' to data type int.
-- 해결 방법 1: TRY_CAST 사용
SELECT TRY_CAST('abc' AS INT) AS 결과; -- NULL 반환
-- 해결 방법 2: ISNUMERIC으로 사전 확인
SELECT
CASE
WHEN ISNUMERIC('abc') = 1 THEN CAST('abc' AS INT)
ELSE NULL
END AS 결과;
오류 2: 데이터 손실
-- 소수점 손실 주의
SELECT
CAST(123.456 AS INT) AS 소수점버림, -- 123
CAST(123.456 AS DECIMAL(5,2)) AS 반올림, -- 123.46
CAST(123.456 AS DECIMAL(5,1)) AS 반올림2; -- 123.5
-- 문자열 길이 초과 주의
SELECT
CAST('This is a very long text' AS VARCHAR(10)) AS 잘린문자열;
-- 'This is a '
오류 3: 날짜 형식 불일치
-- 잘못된 날짜 형식
SELECT CONVERT(DATE, '04-10-2025'); -- 혼란 발생 가능
-- 명확한 형식 지정
SELECT CONVERT(DATE, '04-10-2025', 105); -- dd-mm-yyyy 형식 명시
-- 또는 ISO 형식 사용 (권장)
SELECT CONVERT(DATE, '2025-10-04', 23); -- yyyy-mm-dd (명확)
마무리: 타입 변환 마스터 체크리스트
✅ CAST와 CONVERT의 차이를 이해하고 상황에 맞게 선택할 수 있나요?
✅ CONVERT의 스타일 코드로 날짜를 원하는 형식으로 표시할 수 있나요?
✅ TRY_CAST/TRY_CONVERT로 안전한 변환을 구현할 수 있나요?
✅ 암시적 변환의 성능 문제를 이해하고 있나요?
✅ 인덱스 컬럼 변환 시 주의사항을 알고 있나요?
✅ 데이터 손실 없이 정확한 타입 변환을 할 수 있나요?
✅ 실무 시나리오에 타입 변환을 효과적으로 적용할 수 있나요?
데이터 타입 변환은 SQL 쿼리 작성의 기본이면서도 가장 중요한 기술입니다. CAST와 CONVERT를 제대로 이해하고 활용하면 데이터 처리의 정확성과 효율성을 동시에 높일 수 있습니다. 이 글의 예제들을 실제 쿼리에 적용하여 데이터베이스 마스터로 한 걸음 나아가세요!
시리즈 다음 글: “MSSQL 문자열 함수 완벽 가이드 – SUBSTRING, CHARINDEX, REPLACE 활용법”으로 찾아뵙겠습니다.
참고 자료
- Microsoft Docs – CAST and CONVERT
- Microsoft Docs – Date and Time Styles
- Microsoft Docs – TRY_CAST
- Microsoft Docs – TRY_CONVERT