소스: sql-src/mid_06_null_funcs/01_coalesce_nullif.sql. 샘플 스키마에 직원 연락처(emp_contact)와 부서별 목표·실적(sales_stat) 테이블을 추가했습니다. emp_contact 는 휴대폰·사무실·이메일 중 일부만 채워진 직원이 섞여 있고, sales_stat 은 목표(target)가 0 이거나 NULL 인 부서가 있습니다.
SELECT
emp_id
, mobile
, office
, email
, COALESCE(mobile, office, email, '연락처 없음') AS contact
FROM emp_contact
ORDER BY emp_id;EMP_ID | MOBILE | OFFICE | EMAIL | CONTACT
-------+---------------+-------------+---------------+--------------
1 | 010-1111-2222 | NULL | kim@test.com | 010-1111-2222
2 | NULL | 02-111-2222 | lee@test.com | 02-111-2222
3 | NULL | NULL | park@test.com | park@test.com
4 | NULL | NULL | NULL | 연락처 없음
5 | 010-5555-6666 | 02-555-6666 | NULL | 010-5555-6666
(5행)휴대폰이 있으면 휴대폰, 없으면 사무실, 그것도 없으면 이메일 순으로 값을 고릅니다. 4번 직원처럼 셋 다 NULL 이면 마지막 인자인 '연락처 없음' 이 나옵니다.
SELECT dept, target, actual, actual / target AS pct FROM sales_stat ORDER BY dept;예상 오류: Division by zero: "120"개발팀의 target 이 0 이라 정수 나눗셈이 오류로 끝났습니다. 부서 하나의 데이터 때문에 전체 조회가 실패하는 흔한 장애 패턴입니다.
SELECT
dept
, target
, actual
, actual * 100 / NULLIF(target, 0) AS pct
FROM sales_stat
ORDER BY dept;DEPT | TARGET | ACTUAL | PCT
-----+--------+--------+-----
개발 | 0 | 120 | NULL
영업 | 500 | 430 | 86
인사 | NULL | 80 | NULL
지원 | 200 | 0 | 0
(4행)target 이 0 인 개발팀은 NULLIF 가 0 을 NULL 로 바꿔 나눗셈 결과가 NULL 이 되고, 오류 없이 나머지 행이 정상 계산됩니다. target 이 원래 NULL 인 인사팀도 결과는 NULL 로 같지만, 이쪽은 NULLIF 없이도 "NULL 로 나누면 NULL"이라는 규칙만으로 NULL 이 됩니다.
SELECT
id
, name
, mgr
, sal
, sal + mgr AS raw_sum
, sal + COALESCE(mgr, 0) AS safe_sum
FROM emp
ORDER BY id;ID | NAME | MGR | SAL | RAW_SUM | SAFE_SUM
---+--------+------+-----+---------+---------
1 | 김대표 | NULL | 900 | NULL | 900
2 | 이팀장 | 1 | 650 | 651 | 651
3 | 박선임 | 2 | 500 | 502 | 502
4 | 최사원 | 2 | 350 | 352 | 352
5 | 정팀장 | 1 | 600 | 601 | 601
(5행)김대표는 상사(mgr)가 없어 sal + mgr 이 NULL 입니다. +·-·*·/ 어떤 연산자든 NULL 이 하나만 섞여도 전체 결과가 NULL 이 되며, COALESCE 로 NULL 을 0 으로 바꾼 safe_sum 만 정상 값이 나옵니다.
SELECT
emp_id
, mobile
, office
, mobile || '/' || office AS raw_concat
, COALESCE(mobile, '') || '/' || COALESCE(office, '') AS safe_concat
FROM emp_contact
ORDER BY emp_id;EMP_ID | MOBILE | OFFICE | RAW_CONCAT | SAFE_CONCAT
-------+---------------+-------------+---------------------------+--------------------------
1 | 010-1111-2222 | NULL | NULL | 010-1111-2222/
2 | NULL | 02-111-2222 | NULL | /02-111-2222
3 | NULL | NULL | NULL | /
4 | NULL | NULL | NULL | /
5 | 010-5555-6666 | 02-555-6666 | 010-5555-6666/02-555-6666 | 010-5555-6666/02-555-6666
(5행)office 나 mobile 중 하나라도 NULL 이면 || 로 연결한 raw_concat 은 통째로 NULL 입니다. COALESCE 로 NULL 을 빈 문자열로 먼저 바꾼 safe_concat 만 나머지 값이 살아남습니다.