PostgreSQL에서 자주 사용하는 내장 함수를 카테고리별로 정리합니다.
문자열 함수
| 함수 |
설명 |
예시 |
결과 |
\|\| |
문자열 연결 |
'Hello' \|\| ' ' \|\| 'World' |
Hello World |
| CONCAT |
문자열 연결 (NULL 무시) |
CONCAT('A', NULL, 'B') |
AB |
| CONCAT_WS |
구분자로 연결 |
CONCAT_WS('-', '2024', '01', '15') |
2024-01-15 |
| SUBSTRING |
부분 문자열 |
SUBSTRING('Hello' FROM 1 FOR 3) |
Hel |
| LEFT / RIGHT |
왼쪽/오른쪽 n자 |
LEFT('Hello', 2) |
He |
| LENGTH |
문자 길이 |
LENGTH('가나다') |
3 |
| OCTET_LENGTH |
바이트 길이 |
OCTET_LENGTH('가나다') |
9 |
| UPPER / LOWER |
대/소문자 |
UPPER('hello') |
HELLO |
| INITCAP |
첫 글자 대문자 |
INITCAP('hello world') |
Hello World |
| TRIM |
공백/문자 제거 |
TRIM(' hi ') |
hi |
| LTRIM / RTRIM |
좌/우 제거 |
LTRIM('xxhi', 'x') |
hi |
| REPLACE |
문자열 치환 |
REPLACE('abc', 'b', 'x') |
axc |
| LPAD / RPAD |
패딩 |
LPAD('5', 3, '0') |
005 |
| REVERSE |
뒤집기 |
REVERSE('abc') |
cba |
| POSITION |
위치 찾기 |
POSITION('lo' IN 'Hello') |
4 |
| SPLIT_PART |
구분자로 분리 |
SPLIT_PART('a-b-c', '-', 2) |
b |
| REGEXP_REPLACE |
정규식 치환 |
REGEXP_REPLACE('abc123', '[0-9]', '', 'g') |
abc |
| TRANSLATE |
문자 단위 치환 |
TRANSLATE('abc', 'abc', 'xyz') |
xyz |
| FORMAT |
포맷 문자열 |
FORMAT('Hello %s, age %s', '홍길동', 30) |
Hello 홍길동, age 30 |
-- 이메일에서 도메인 추출
SELECT SPLIT_PART(email, '@', 2) AS domain FROM users;
-- 이름 마스킹
SELECT LEFT(name, 1) || '**' AS masked_name FROM employees;
-- 정규식 매칭
SELECT name FROM employees WHERE name ~ '^[가-힣]+$'; -- 한글만
숫자 함수
| 함수 |
설명 |
예시 |
결과 |
| ROUND |
반올림 |
ROUND(3.456, 2) |
3.46 |
| CEIL / CEILING |
올림 |
CEIL(3.1) |
4 |
| FLOOR |
내림 |
FLOOR(3.9) |
3 |
| TRUNC |
절삭 |
TRUNC(3.456, 2) |
3.45 |
| ABS |
절대값 |
ABS(-5) |
5 |
| MOD |
나머지 |
MOD(10, 3) |
1 |
| POWER |
거듭제곱 |
POWER(2, 10) |
1024 |
| SQRT |
제곱근 |
SQRT(16) |
4 |
| RANDOM |
난수 (0~1) |
RANDOM() |
0.7342… |
| GREATEST |
최대값 |
GREATEST(1, 5, 3) |
5 |
| LEAST |
최소값 |
LEAST(1, 5, 3) |
1 |
-- 랜덤 정렬
SELECT * FROM employees ORDER BY RANDOM() LIMIT 3;
-- 급여를 만원 단위로 반올림
SELECT name, ROUND(salary, -4) AS rounded FROM employees;
날짜/시간 함수
| 함수 |
설명 |
MySQL 대응 |
| NOW() |
현재 날짜+시간 (트랜잭션 시작 시점) |
NOW() |
| CURRENT_TIMESTAMP |
NOW()와 동일 |
CURRENT_TIMESTAMP |
| CURRENT_DATE |
현재 날짜 |
CURDATE() |
| CURRENT_TIME |
현재 시간 |
CURTIME() |
| CLOCK_TIMESTAMP() |
실제 현재 시각 (호출 시점) |
없음 |
| EXTRACT |
연/월/일 추출 |
EXTRACT |
| DATE_TRUNC |
날짜 절삭 |
없음 |
| AGE |
두 날짜 간 차이 |
TIMESTAMPDIFF |
| DATE_PART |
날짜 부분 추출 |
YEAR(), MONTH() |
| TO_CHAR |
날짜 포맷 |
DATE_FORMAT |
| TO_DATE |
문자→날짜 |
STR_TO_DATE |
| TO_TIMESTAMP |
문자→타임스탬프 |
STR_TO_DATE |
| INTERVAL |
시간 간격 |
INTERVAL |
-- 현재 날짜/시간
SELECT NOW(); -- 2026-05-04 14:30:00+09
SELECT CURRENT_DATE; -- 2026-05-04
SELECT CLOCK_TIMESTAMP(); -- 실제 호출 시점 (반복 호출 시 값이 다름)
-- 날짜 연산 (INTERVAL 사용)
SELECT NOW() + INTERVAL '7 days';
SELECT NOW() - INTERVAL '1 month';
SELECT NOW() + INTERVAL '2 hours 30 minutes';
-- EXTRACT
SELECT EXTRACT(YEAR FROM NOW()); -- 2026
SELECT EXTRACT(MONTH FROM NOW()); -- 5
SELECT EXTRACT(DOW FROM NOW()); -- 0(일)~6(토)
-- DATE_TRUNC (날짜 절삭, PostgreSQL 전용)
SELECT DATE_TRUNC('month', NOW()); -- 2026-05-01 00:00:00
SELECT DATE_TRUNC('year', NOW()); -- 2026-01-01 00:00:00
SELECT DATE_TRUNC('hour', NOW()); -- 2026-05-04 14:00:00
-- AGE (두 날짜 간 차이)
SELECT AGE(NOW(), '2024-01-01'); -- 2 years 4 mons 3 days
-- TO_CHAR (날짜 포맷)
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS');
SELECT TO_CHAR(NOW(), 'YYYY"년" MM"월" DD"일"');
-- TO_DATE / TO_TIMESTAMP
SELECT TO_DATE('2026-05-04', 'YYYY-MM-DD');
SELECT TO_TIMESTAMP('2026-05-04 14:30:00', 'YYYY-MM-DD HH24:MI:SS');
-- 입사 후 근속 연수
SELECT name, hire_date,
EXTRACT(YEAR FROM AGE(NOW(), hire_date))::INTEGER AS 근속연수
FROM employees;
NULL 처리 함수
| PostgreSQL |
MySQL 대응 |
설명 |
| COALESCE(a, b, …) |
COALESCE / IFNULL |
첫 번째 NOT NULL 값 |
| NULLIF(a, b) |
NULLIF |
a=b이면 NULL |
SELECT COALESCE(dept, '미배정') FROM employees;
SELECT NULLIF(salary, 0); -- 0이면 NULL 반환
PostgreSQL에는 MySQL의 IFNULL이나 Oracle의 NVL이 없습니다. COALESCE를 사용합니다.
조건 함수
-- CASE (표준 SQL)
SELECT name, CASE WHEN salary >= 5000000 THEN '고연봉' ELSE '일반' END FROM employees;
-- PostgreSQL에는 MySQL의 IF() 함수가 없습니다. CASE를 사용합니다.
타입 변환
-- CAST (표준)
SELECT CAST('123' AS INTEGER);
SELECT CAST('2026-05-04' AS DATE);
-- :: 연산자 (PostgreSQL 전용, 더 간결)
SELECT '123'::INTEGER;
SELECT '2026-05-04'::DATE;
SELECT 3.14::TEXT;
SELECT salary::INTEGER FROM employees;
윈도우 함수
-- ROW_NUMBER
SELECT name, dept_id, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS 순위
FROM employees;
-- RANK / DENSE_RANK
SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS rank_순위,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_순위
FROM employees;
-- 부서별 급여 순위
SELECT name, dept_id, salary,
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS 부서내순위
FROM employees;
-- LAG / LEAD
SELECT name, salary,
LAG(salary) OVER (ORDER BY salary) AS 이전급여,
LEAD(salary) OVER (ORDER BY salary) AS 다음급여
FROM employees;
-- 누적 합계
SELECT name, salary,
SUM(salary) OVER (ORDER BY hire_date) AS 누적급여
FROM employees;
-- FIRST_VALUE / LAST_VALUE
SELECT name, dept_id, salary,
FIRST_VALUE(name) OVER (PARTITION BY dept_id ORDER BY salary DESC) AS 부서최고연봉자
FROM employees;
-- NTILE
SELECT name, salary,
NTILE(4) OVER (ORDER BY salary DESC) AS 분위
FROM employees;
관련된 글 (postgresql > lecture-postgresql)