SQL을 쓰다 보면 단순히 데이터를 꺼내는 것 이상이 필요해진다. 이름을 대문자로 바꾸거나, 날짜 차이를 계산하거나, 소수점을 정리하거나. 이런 처리를 쿼리 안에서 바로 할 수 있게 해주는 것이 내장 함수다.
자주 쓰는 것들만 추렸다.
여러 문자열을 이어 붙인다.
SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM members;
full_name
---------
김 민수
이 지현
문자열의 일부를 잘라낸다. 시작 위치는 1부터 센다.
-- SUBSTRING(문자열, 시작위치, 길이)
SELECT SUBSTRING('Hello World', 1, 5); -- Hello
SELECT SUBSTRING('Hello World', 7); -- World (끝까지)
LENGTH는 바이트 수, CHAR_LENGTH는 문자 수를 반환한다. 한글처럼 멀티바이트 문자를 다룰 때 차이가 난다.
SELECT LENGTH('안녕'); -- 6 (UTF-8에서 한글 1자 = 3바이트)
SELECT CHAR_LENGTH('안녕'); -- 2 (문자 수)
한글 문자열의 실제 글자 수를 셀 때는 CHAR_LENGTH를 쓴다.
문자열을 대문자 또는 소문자로 변환한다.
SELECT UPPER('hello'); -- HELLO
SELECT LOWER('WORLD'); -- world
이메일이나 코드값을 비교할 때 대소문자를 통일하는 용도로 자주 쓴다.
문자열 앞뒤의 공백을 제거한다.
SELECT TRIM(' hello '); -- 'hello'
사용자 입력값에 공백이 섞여 들어오는 경우 WHERE 조건 전에 정리할 때 쓴다.
특정 문자열을 다른 문자열로 교체한다.
-- REPLACE(대상, 찾을 문자열, 바꿀 문자열)
SELECT REPLACE('010-1234-5678', '-', ''); -- 01012345678
지정한 소수점 자리에서 반올림한다.
SELECT ROUND(3.456, 2); -- 3.46
SELECT ROUND(3.456, 0); -- 3
SELECT ROUND(3.456, -1); -- 0 (일의 자리에서 반올림)
CEIL은 올림, FLOOR는 내림이다.
SELECT CEIL(3.1); -- 4
SELECT FLOOR(3.9); -- 3
절댓값을 반환한다.
SELECT ABS(-15); -- 15
SELECT ABS(15); -- 15
두 값의 차이를 구할 때 음수가 나오지 않도록 할 때 쓴다.
나머지를 반환한다. % 연산자와 동일하다.
SELECT MOD(10, 3); -- 1
SELECT 10 % 3; -- 1
현재 날짜와 시간을 반환한다.
SELECT NOW(); -- 2026-04-18 14:30:00 (날짜 + 시간)
SELECT CURDATE(); -- 2026-04-18 (날짜만)
SELECT CURTIME(); -- 14:30:00 (시간만)
날짜를 원하는 형식의 문자열로 변환한다.
SELECT DATE_FORMAT(NOW(), '%Y년 %m월 %d일'); -- 2026년 04월 18일
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d'); -- 2026-04-18
자주 쓰는 포맷 기호:
| 기호 | 의미 |
|---|---|
%Y | 4자리 연도 |
%m | 2자리 월 |
%d | 2자리 일 |
%H | 24시간 기준 시 |
%i | 분 |
%s | 초 |
두 날짜 사이의 일수 차이를 반환한다.
-- DATEDIFF(기준날짜, 빼는날짜)
SELECT DATEDIFF('2026-04-18', '2026-01-01'); -- 107
날짜에 특정 기간을 더하거나 뺀다.
SELECT DATE_ADD('2026-04-18', INTERVAL 7 DAY); -- 2026-04-25
SELECT DATE_SUB('2026-04-18', INTERVAL 1 MONTH); -- 2026-03-18
집계 함수는 여러 행을 하나의 결과로 요약한다. 보통 GROUP BY와 함께 쓴다.
행의 개수를 센다. COUNT(*)는 NULL 포함 전체 행, COUNT(컬럼)은 NULL 제외한 개수다.
SELECT COUNT(*) FROM orders; -- 전체 주문 수
SELECT COUNT(DISTINCT member_id) FROM orders; -- 주문한 회원 수 (중복 제거)
합계와 평균을 구한다.
SELECT SUM(price) AS 총매출 FROM orders;
SELECT AVG(price) AS 평균금액 FROM orders;
최댓값과 최솟값을 반환한다.
SELECT MAX(price) AS 최고가 FROM products;
SELECT MIN(price) AS 최저가 FROM products;
집계 함수의 진짜 쓸모는 GROUP BY와 붙었을 때 나온다.
-- 회원별 주문 횟수와 총 결제금액
SELECT
member_id,
COUNT(*) AS 주문횟수,
SUM(price) AS 총결제금액
FROM orders
GROUP BY member_id;
member_id | 주문횟수 | 총결제금액
----------+--------+---------
1 | 3 | 75000
2 | 1 | 32000
특정 조건으로 그룹 결과를 필터링할 때는 WHERE 대신 HAVING을 쓴다.
-- 주문 횟수가 2번 이상인 회원만
SELECT member_id, COUNT(*) AS 주문횟수
FROM orders
GROUP BY member_id
HAVING COUNT(*) >= 2;
함수 이름은 외우려고 하면 끝이 없다. 어떤 처리가 필요한 상황이 생겼을 때 "이런 함수가 있지 않을까" 하고 찾아보는 게 더 빠르다. 자주 쓰다 보면 자연스럽게 익혀진다.