함수, NULL, WHERE 조건식
문자·숫자·날짜·변환 함수의 용도와 NULL 처리, WHERE 조건의 우선순위를 시험 문제 풀이 기준으로 정리합니다.
NVLCOALESCECASESUBSTRROUNDLIKE 함수는 “값을 바꾸거나 계산하는 도구”
SQL 함수는 한 행의 값을 가공하는 단일행 함수와 여러 행을 모아 계산하는 집계 함수로 나누어 생각하면 쉽습니다. 이 챕터에서는 WHERE와 SELECT에서 자주 쓰는 단일행 함수를 먼저 살펴봅니다.
문자 함수
| 목적 | 대표 함수 | 예시 감각 |
|---|---|---|
| 대소문자 변환 | LOWER, UPPER | 검색 전 대소문자 통일 |
| 문자열 붙이기 | CONCAT(a,b), || | 성과 이름을 하나로 표시 |
| 일부 추출 | SUBSTR(s, 시작, 길이) | 주민번호 앞자리, 코드 일부 |
| 위치 찾기 | INSTR(s, 부분) | 특정 문자의 위치 (1-based, 없으면 0) |
| 길이 확인 | LENGTH / LENGTHB | 문자 수 / 바이트 수 |
| 좌우 채우기 | LPAD, RPAD | 자리수 맞춘 번호 표시 |
| 치환 | REPLACE(s, from, to) | 문자열 전체 치환 |
| 문자 치환 | TRANSLATE(s, from, to) | 문자 단위 일대일 치환 |
| 공백·문자 제거 | LTRIM, RTRIM, TRIM | 앞뒤 불필요한 문자 제거 |
SELECT UPPER(ename) AS upper_name,
SUBSTR(ename, 1, 2) AS name_prefix
FROM emp;
숫자 함수
| 함수 | 의미 | 결과 예 |
|---|---|---|
ABS(-15) | 절댓값 | 15 |
SIGN(n) | 부호 (양수 1, 음수 -1, 0) | SIGN(-7) = -1 |
MOD(10, 3) | 나머지 | 1 |
CEIL(38.1) | 올림 | 39 |
FLOOR(38.9) | 내림 | 38 |
ROUND(38.567, 2) | 반올림 (자릿수 음수 가능) | 38.57 |
TRUNC(38.567, 2) | 버림 | 38.56 |
POWER(2, 10) | 거듭제곱 | 1024 |
SQRT(4) | 제곱근 | 2 |
GREATEST(a,b,c) | 최댓값 (인자 중 NULL 있으면 NULL) | — |
LEAST(a,b,c) | 최솟값 | — |
날짜와 변환 함수
날짜 함수는 DBMS마다 이름이 다릅니다. Oracle은 SYSDATE, SQL Server는 GETDATE()로 현재 시각을 얻는 식입니다.
| 함수 | 의미 |
|---|---|
SYSDATE | 현재 날짜+시각 (Oracle) |
SYSDATE + 7 | 7일 뒤 날짜 (정수는 ‘일’ 단위) |
SYSDATE + 1/24 | 1시간 뒤 (1/24 = 1시간) |
MONTHS_BETWEEN(d1, d2) | 두 날짜의 개월 수 (소수 가능) |
ADD_MONTHS(d, n) | n개월 더한 날짜 |
NEXT_DAY(d, '금요일') | d 이후 가장 가까운 금요일 |
LAST_DAY(d) | d가 속한 월의 마지막 날 |
EXTRACT(MONTH FROM d) | 날짜에서 특정 부분 추출 (숫자) |
TO_CHAR(d, 'YYYY-MM-DD') | 날짜 → 문자 (포맷 자유) |
TO_DATE(s, 'YYYY-MM-DD') | 문자 → 날짜 |
TO_NUMBER('1234') | 문자 → 숫자 |
CASE 표현식과 DECODE
CASE는 SQL 안에서 조건별 값을 만드는 표준 방식입니다. DECODE는 Oracle 전용 축약형입니다.
CASE (ANSI 표준)
CASE sal
WHEN 1000 THEN 'LOW'
WHEN 2000 THEN 'MID'
ELSE 'HIGH'
END
범위·NULL 등 복잡한 조건도 가능합니다 (검색형).
DECODE (Oracle 전용)
DECODE(sal,
1000, 'LOW',
2000, 'MID',
'HIGH')
값의 동등 비교만 가능합니다. 중첩 시 가독성이 낮아집니다.
CASE는 위에서부터 조건을 확인합니다. 먼저 만족한 조건의 결과가 반환되므로, 범위가 겹칠 때는 순서가 중요합니다.
SELECT ename,
CASE
WHEN sal >= 3000 THEN 'HIGH'
WHEN sal >= 1500 THEN 'MID'
ELSE 'LOW'
END AS sal_grade
FROM emp;
NULL은 값이 아니라 “모름”
SQLD에서 NULL은 거의 매회 유의 사항으로 나옵니다. NULL은 0도 아니고 빈 문자열도 아니며, “아직 알 수 없음” 에 가깝습니다.
| 표현 | 결과 감각 |
|---|---|
col = NULL | 비교 결과가 UNKNOWN이며 TRUE가 아닙니다 |
col <> NULL | 이것도 UNKNOWN이며 TRUE가 아닙니다 |
col + NULL | NULL (산술 연산에 NULL이 참여하면 결과가 NULL) |
col || NULL | Oracle에서는 col 그대로 (||는 NULL을 빈 문자열로 취급) |
col IS NULL | NULL 검사 |
col IS NOT NULL | NULL이 아닌 값 검사 |
SELECT ename
FROM emp
WHERE comm IS NULL;
NULL을 다른 값처럼 =, <>로 비교하면 조건을 통과하지 못합니다. IS NULL 또는 IS NOT NULL을 사용하시기 바랍니다.
NULL 처리 함수
| 함수 | 의미 |
|---|---|
NVL(a, b) | 2개 인자. Oracle에서 a가 NULL이면 b |
NVL2(a, b, c) | Oracle 3항. a가 NULL이 아니면 b, NULL이면 c |
ISNULL(a, b) | SQL Server에서 NVL과 동일 |
COALESCE(a, b, c, ...) | 가변 인자 ANSI 표준. NULL이 아닌 첫 값 반환 |
NULLIF(a, b) | 두 값이 같으면 NULL, 다르면 a 반환 |
SELECT ename, sal + COALESCE(comm, 0) AS total_pay
FROM emp;
수당 comm이 NULL이면 sal + comm도 NULL이 될 수 있습니다. 계산 전에 COALESCE(comm, 0)처럼 바꾸면 결과가 안정적입니다.
부정 비교 연산자
Oracle은 “같지 않다”를 세 가지로 표현합니다. ANSI는 두 가지입니다.
| 연산자 | DB 지원 | 의미 |
|---|---|---|
<> | ANSI 표준 | 같지 않다 |
!= | ANSI 표준 | 같지 않다 |
^= | Oracle 전용 | 같지 않다 |
WHERE 조건의 우선순위
조건식은 다음 순서로 해석됩니다.
| 순위 | 연산자 |
|---|---|
| 1 | 괄호 () |
| 2 | 비교 (=, <, >, …) · SQL (BETWEEN, IN, LIKE, IS NULL) |
| 3 | NOT |
| 4 | AND |
| 5 | OR |
WHERE job = 'SALESMAN'
OR job = 'CLERK'
AND sal >= 1000
위 조건은 AND가 OR보다 먼저이므로 CLERK에게만 급여 조건이 적용됩니다. 즉 SALESMAN 전원과 급여 1000 이상인 CLERK이 선택됩니다. 두 직무 모두에게 급여 조건을 적용하려면 괄호를 써야 합니다.
WHERE (job = 'SALESMAN' OR job = 'CLERK')
AND sal >= 1000
함수는 값을 바꾸고, WHERE는 행을 거르며, NULL은 IS NULL로만 검사합니다.