CodeGym /행동 /SQL SELF /데이터 타입 비교와 변환

데이터 타입 비교와 변환

SQL SELF
레벨 16 , 레슨 3
사용 가능

이런 거 왜 배워야 하냐고? 비교랑 변환이 왜 필요하냐면, 예를 들어 테이블에 "42"라는 문자열이 있는데, 이걸 숫자 42랑 비교하고 싶다고 해봐. 겉보기엔 똑같아 보이지만, DB 입장에선 완전 다른 거야. PostgreSQL은 네가 뭘 의도했는지 자동으로 추측 안 해줘. 서로 다른 타입을 어떻게 비교하는지 모르면, 이상한 결과가 나오거나 아예 에러가 날 수도 있어.

변환도 마찬가지야. 가끔은 텍스트를 숫자로 바꿔서 뭔가 개수를 세야 할 때가 있고, 반대로 숫자를 예쁘게 문자열로 보여줘야 할 때도 있지. 아니면 날짜를 "01.01.2025"처럼 익숙한 포맷으로 보여주고 싶을 수도 있고.

또 다른 예시! 정확한 값은 NUMERIC에 저장돼 있는데, 과학 계산하려면 FLOAT로 써야 할 때가 있어. 이런 경우엔 명시적으로 변환 안 하면 답이 없어.

좋은 소식은 PostgreSQL이 이런 거 진짜 잘 처리해준다는 거야. 이런 작업을 위한 유연하고 직관적인 도구들이 많아. 중요한 건, 그걸 어떻게 쓰는지 알고, 겁내지 말고 내부 동작도 조금씩 들여다보는 거지. 이제 같이 해보자!

데이터 타입 비교

PostgreSQL은 똑똑한 척을 해. 예를 들어 INTEGERNUMERIC을 비교하면, 알아서 공통 타입으로 맞춰서 비교해줘. 둘 다 숫자니까 괜찮지.

근데 만약 문자열이랑 불리언(TEXTBOOLEAN)을 비교하려고 하면, DB는 네가 뭘 원하는지 전혀 몰라. 타입 자체가 완전 다르니까 PostgreSQL은 그냥 에러를 뱉어. 마찬가지로 "42"라는 문자열이랑 숫자 42를 변환 없이 비교하면 에러 나.

실제로 어떻게 되는지 볼까? 이건 에러가 나오는 예시야:

SELECT '42' = 42; -- 에러! 문자열이랑 숫자는 변환 없이 비교 안 돼

이렇게 하면 제대로 동작해:

SELECT '42'::INTEGER = 42; -- TRUE

여기서 우리가 명확하게 말해주는 거야: “'42'를 먼저 숫자로 바꿔줘.” 이럴 때 ::타입 문법을 쓰는 거고, PostgreSQL은 이런 식으로 명확하게 말해주는 걸 좋아해.

숫자 타입 비교

숫자 타입(INTEGER, NUMERIC, REAL)끼리는 대부분 호환돼서, 별 문제 없이 비교할 수 있어:

SELECT 42 = 42.0; -- TRUE
SELECT 42::REAL = 42.0; -- TRUE
SELECT 42.0::NUMERIC = 42; -- TRUE

근데 REAL처럼 소수점 있는 숫자는 조심해야 해. 정밀도가 한계가 있어서, 가끔 이상하게 동작할 수 있거든. 예를 들어:

SELECT 0.1 + 0.2 = 0.3; -- FALSE

이거 프로그래밍에서 제일 유명한 미스터리 아니냐? 여기선 컴퓨터 메모리에서 소수 저장 방식 때문에 FALSE가 나와.

문자열 타입 비교

문자열 타입 다룰 때는 CHAR, VARCHAR, TEXT끼리 비교해도 돼. PostgreSQL이 알아서 호환되는 타입으로 바꿔줘:

SELECT 'Hello' = 'Hello'::TEXT; -- TRUE
SELECT 'World'::CHAR(5) = 'World'::VARCHAR; -- TRUE

CHAR(n)에서 문자 길이 주의! 문자열이 지정한 길이보다 짧으면 PostgreSQL이 뒤에 공백을 채워버려.

데이터 타입 변환

PostgreSQL은 데이터 타입 변환 방법을 여러 개 제공해. 대표적으로 두 가지 방법을 볼 거야:

방법 1: 명시적 변환 (CAST)

CAST 연산자는 한 타입을 다른 타입으로 어떻게 바꿀지 지정해줘. 예시:

SELECT CAST('42' AS INTEGER); -- 문자열 '42'를 숫자 42로 변환

이 방법은 SQL 코드를 좀 더 읽기 쉽게 만들고 싶을 때 특히 좋아.

방법 2: 축약형 문법 (::)

PostgreSQL은 ::를 쓰는 짧은 문법도 지원해. 같은 동작인데 더 간단하게 쓸 수 있어:

SELECT '42'::INTEGER; -- CAST('42' AS INTEGER)랑 똑같아

자동 변환

많은 경우에 PostgreSQL이 자동으로 타입을 변환해줘. 예를 들어 문자열 필드에 숫자를 쓸 때:

SELECT '42' = 42::TEXT; -- TRUE

근데 자동 변환만 믿으면 위험할 수도 있어. 다른 개발자 입장에선 헷갈릴 수 있거든. 특히 날짜랑 문자열은 명시적으로 변환하는 게 좋아.

다양한 데이터 타입 변환 예제

숫자를 문자열로 변환

가끔 숫자를 문자열로 바꿔야 할 때가 있어 (예를 들어 메시지 만들 때):

SELECT 42::TEXT; -- 숫자 42를 문자열 '42'로 변환
SELECT 3.14::TEXT; -- 숫자 3.14를 문자열 '3.14'로 변환

문자열을 숫자로 변환

문자열에 올바른 숫자가 들어있으면, 숫자 타입으로 변환할 수 있어:

SELECT '123'::INTEGER; -- 문자열 '123'을 숫자 123으로 변환
SELECT '3.14'::FLOAT;  -- 문자열 '3.14'를 숫자 3.14로 변환

근데 텍스트가 숫자로 변환 안 되면 어떻게 될까? 예를 들어:

SELECT 'Hello'::INTEGER; -- 에러: 'Hello'를 숫자로 변환할 수 없음

이런 에러를 피하려면 TRY_CAST() 함수(PostgreSQL 14부터 지원)나, 미리 데이터 체크하는 게 좋아.

날짜를 문자열로, 문자열을 날짜로 변환

날짜 변환할 땐 TO_CHAR()TO_DATE() 함수 써봐:

SELECT TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD'); -- 날짜를 문자열로 변환
SELECT TO_DATE('2023-10-25', 'YYYY-MM-DD'); -- 문자열을 날짜로 변환

BOOLEAN과 문자열 변환

BOOLEAN 타입도 문자열로 변환할 수 있어:

SELECT TRUE::TEXT; -- 'true'
SELECT FALSE::TEXT; -- 'false'

반대로도 가능해:

SELECT 'true'::BOOLEAN; -- TRUE
SELECT 'false'::BOOLEAN; -- FALSE

'yes''no' 같은 문자열은 자동 변환 안 돼. 주의!

실전: 진짜 예제로 연습해보자

여러 타입을 사용하는 테이블을 만들어볼게:

id number_as_text - TEXT number_as_integer - INTEGER date_as_text - TEXT actual_date - DATE
1 42 42 2023-10-25 2023-10-25
2 3.14 NULL 2023-10-24 NULL
3 Hello 123 NULL NULL

이제 변환 연산을 해보자:

-- 문자열을 숫자로 변환
SELECT number_as_text::INTEGER FROM data_types_demo WHERE number_as_text = '42';

-- 날짜를 문자열로 변환
SELECT TO_CHAR(actual_date, 'DD/MM/YYYY') FROM data_types_demo;

-- 문자열을 날짜로 변환
SELECT TO_DATE(date_as_text, 'YYYY-MM-DD') FROM data_types_demo;

데이터 변환에서 흔한 실수

흔한 실수는 이런 것들이야:

  1. 예상한 포맷이 아닌 데이터를 변환하려고 시도함 (예: 'Hello'INTEGER로 변환).
  2. 소수점 숫자 다룰 때 반올림, 정밀도 문제.
  3. 날짜 변환할 때 포맷을 잘못 씀.

이런 실수를 막으려면:

  • 변환 전에 항상 데이터를 체크해.
  • 에러 처리 함수(TRY_CASTCASE)를 써.
  • 날짜 변환할 땐 포맷을 명확하게 지정해.
-- 변환 전에 데이터 체크
SELECT 
    CASE 
        WHEN number_as_text ~ '^\d+$' THEN number_as_text::INTEGER
        ELSE NULL
    END AS safe_integer
FROM data_types_demo;

이런 식으로 쿼리를 짜면, 예상 못한 상황에서도 안전하게 동작할 수 있어!

이제 PostgreSQL에서 데이터 타입 비교랑 변환 기본기는 갖췄어. 남은 건 연습, 연습, 또 연습뿐! 다음 강의에서 또 보자~

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION