공공부하자개발 · 영어 학습 노트
SQL
SQL 중급서브쿼리·조인·함수·DDL·인덱스0/11 완료
  • 01서브쿼리: 스칼라·인라인 뷰·상관 서브쿼리, DB별 차이
  • 02EXISTS·IN·NOT IN 과 NULL 함정
  • 03조인 심화: INNER·OUTER·SELF·CROSS, Oracle (+)
  • 04집합 연산: UNION·UNION ALL·INTERSECT·MINUS/EXCEPT
  • 05조건 로직: CASE·DECODE·IIF
  • 06NULL 처리 함수
  • 07문자·날짜 함수 DB별 비교
  • 08DDL 과 제약 조건
  • 09인덱스 기초
  • 10집계와 GROUP BY·HAVING
  • 11뷰·시퀀스·자동 증가
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › SQL 중급 › 07 / 11

문자·날짜 함수 DB별 비교

섹션 6진행 0 / 11
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6정리‹ 이전다음 ›

3. 코드 예제

소스: sql-src/mid_07_string_date/01_string.sql. 직원(emp)과 고객 연락처(cust_info), 문자열 비교용 테이블(str_demo)을 준비했습니다. H2 기본 모드에서 DB를 가리지 않고 쓸 수 있는 표준 문자 함수를 확인합니다.

예제 1: 자르기·찾기·길이·채우기

sql
SELECT
       id
     , name
     , SUBSTR(name, 1, 2)  AS first2
     , INSTR(name, '민')   AS pos_min
     , CHAR_LENGTH(name)   AS char_len
     , OCTET_LENGTH(name)  AS byte_len
     , LPAD(name, 8, '*')  AS lpad_name
     , RPAD(name, 8, '*')  AS rpad_name
  FROM emp
 ORDER BY id;
text
ID | NAME   | FIRST2 | POS_MIN | CHAR_LEN | BYTE_LEN | LPAD_NAME   | RPAD_NAME
---+--------+--------+---------+----------+----------+-------------+------------
1  | 김민준 | 김민   | 2       | 3        | 9        | *****김민준 | 김민준*****
2  | 이서연 | 이서   | 0       | 3        | 9        | *****이서연 | 이서연*****
3  | 최도윤 | 최도   | 0       | 3        | 9        | *****최도윤 | 최도윤*****
(3행)

SUBSTR(name, 1, 2) 는 앞 2글자, INSTR(name, '민') 는 '민' 이 있는 위치로 2·3번 직원처럼 없으면 0입니다. CHAR_LENGTH 는 문자 수(3), OCTET_LENGTH 는 바이트 수(9)로 3배 차이가 나고, LPAD·RPAD 는 목표 길이 8에서 남는 만큼 * 을 왼쪽·오른쪽에 채웁니다.

예제 2: 공백 제거·치환·대소문자

sql
SELECT
       TRIM('   hello   ') AS trimmed
     , LTRIM('   hello')   AS ltrimmed
     , RTRIM('hello   ')   AS rtrimmed
     , REPLACE('hello world', 'world', 'sql') AS replaced
     , UPPER('hello')      AS upper_val
     , LOWER('HELLO')      AS lower_val
  FROM emp
 WHERE id = 1;
text
TRIMMED | LTRIMMED | RTRIMMED | REPLACED  | UPPER_VAL | LOWER_VAL
--------+----------+----------+-----------+-----------+----------
hello   | hello    | hello    | hello sql | HELLO     | hello
(1행)

TRIM 은 양쪽, LTRIM·RTRIM 은 한쪽 공백만 지웁니다. REPLACE 는 첫 번째 인자에서 두 번째 문자열을 찾아 세 번째 문자열로 바꾸고, UPPER·LOWER 는 영문 대소문자를 바꿉니다.

예제 3: 문자 수와 바이트 수 차이(한글)

sql
SELECT
       val
     , CHAR_LENGTH(val)  AS char_len
     , OCTET_LENGTH(val) AS byte_len
  FROM str_demo
 ORDER BY id;
text
VAL       | CHAR_LEN | BYTE_LEN
----------+----------+---------
김민준    | 3        | 9
Seoul     | 5        | 5
서울Seoul | 7        | 11

영문 'Seoul' 은 문자 수와 바이트 수가 5로 같지만, 한글 '김민준' 은 문자 수 3에 바이트 수 9로 3배입니다. 한글과 영문이 섞인 '서울Seoul' 은 문자 수 7(한글 2 + 영문 5), 바이트 수 11(한글 2×3 + 영문 5)로 계산됩니다.

예제 4: 실무 패턴 — 전화번호·주민번호 마스킹

sql
SELECT
       id
     , phone
     , REGEXP_REPLACE(phone, '[0-9]{4}
  

, '****') AS masked_phone
  FROM cust_info
 ORDER BY id;
text
ID | PHONE         | MASKED_PHONE
---+---------------+--------------
1  | 010-1234-5678 | 010-1234-****
2  | 010-5678-1234 | 010-5678-****
3  | 010-9999-8888 | 010-9999-****
(3행)

REGEXP_REPLACE 로 전화번호 끝 4자리 숫자를 **** 로 바꿉니다. 주민번호는 정규식 대신 SUBSTR 조합으로 뒷자리를 가립니다.

sql
SELECT
       id
     , ssn
     , SUBSTR(ssn, 1, 6) || '-' || SUBSTR(ssn, 8, 1) || '******' AS masked_ssn
  FROM cust_info
 ORDER BY id;
text
ID | SSN            | MASKED_SSN
---+----------------+---------------
1  | 900101-1234567 | 900101-1******
2  | 950512-2345678 | 950512-2******
3  | 880303-2456789 | 880303-2******
(3행)

앞 6자리(생년월일)와 뒷자리 첫 숫자(성별 구분)만 남기고 나머지 6자리를 '*' 로 고정해 연결했습니다. 화면·로그·엑셀 다운로드처럼 개인정보가 노출되면 안 되는 곳에 흔히 쓰는 패턴입니다.

예제 직접 실행

아래 폴더의 SQL 파일을 Git Bash 에서 H2 메모리 DB 로 실행합니다. 방언은 파일 안의 SET MODE 로 바꿉니다.

cd sql-src/mid_07_string_date
ls *.sql
bash ../run.sh <파일>.sql
코드 예제
  • 예제 1: 자르기·찾기·길이·채우기
  • 예제 2: 공백 제거·치환·대소문자
  • 예제 3: 문자 수와 바이트 수 차이(한글)
  • 예제 4: 실무 패턴 — 전화번호·주민번호 마스킹
이전 섹션2 핵심 원리3 / 6다음 섹션4 응용 변형 예제