
쿼리를 작성하다보면 각 절마다의 제약사항이나 함수 사용 방법이 헷갈려 풀지 못하는 문제가 더러 있습니다.
그래서 핵심 문법과 자주 사용하는 함수들을 정리해보았습니다. PDF파일도 첨부하였으니 필요하신 분은 다운받아가세요!
1. 기초: SQL 기본 구조
실행 순서: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
SELECT department, COUNT(*) AS cnt
FROM employees
WHERE age > 30
GROUP BY department
HAVING COUNT(*) > 5
ORDER BY cnt DESC
LIMIT 10;
1-1. 기본 절 (Clause)
| 절 | 역할 | 핵심 규칙 |
|---|---|---|
| SELECT | 조회할 컬럼 지정 | GROUP BY 사용 시: 그룹화 컬럼 + 집계함수만 가능 |
| WHERE | 행 필터링 | 집계함수 사용 불가 ❌ |
| GROUP BY | 그룹화 | SELECT 절에 그룹화되지 않은 컬럼 단독 사용 불가 |
| HAVING | 그룹 필터링 | 집계함수 사용 가능 ✅ |
| ORDER BY | 정렬 | DISTINCT/GROUP BY 사용 시 SELECT 외 컬럼 참조 불가 |
1-2. 집계 함수
COUNT(*) -- 전체 행 개수
COUNT(컬럼명) -- NULL 아닌 행 개수
SUM(salary) -- 합계
AVG(salary) -- 평균
MAX(salary), MIN(salary) -- 최대/최소
1-3. 날짜 함수
| 함수 | 설명 | 출력 형식 |
|---|---|---|
NOW() |
현재 날짜/시간 | 2024-10-16 14:30:00 |
CURDATE() |
현재 날짜 | 2024-10-16 |
YEAR(날짜) |
연도 추출 | 2024 |
MONTH(날짜) |
월 추출 | 1~12 |
DATEDIFF(date1, date2) |
날짜 차이 (일) | 정수 |
DATE_ADD(날짜, INTERVAL n DAY) |
날짜 더하기 | 2024-10-23 |
2. 심화: 윈도우 함수, 서브쿼리, CTE
2-1. 윈도우 함수 (Window Function)
대표 윈도우 함수 비교
ROW_NUMBER(): 동일값도 연속 번호RANK(): 동일값 같은 순위, 다음 순위 건너뜀DENSE_RANK(): 동일값 같은 순위, 다음 순위 연속
핵심: GROUP BY처럼 행을 줄이지 않고, 각 행마다 집계/순위 결과 반환
예시
-- 부서별 급여 순위
SELECT name, department, salary,
ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary DESC) AS rn,
RANK() OVER(PARTITION BY department ORDER BY salary DESC) AS rnk
FROM employees;
-- 부서별 급여 합계 (행은 유지)
SELECT name, salary,
SUM(salary) OVER(PARTITION BY department) AS dept_total
FROM employees;
2-2. 서브쿼리 (Subquery)
정의: 쿼리 안에 중첩된 SELECT 문
주요 사용 위치
-- 1. WHERE 절 (가장 흔함)
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
-- 2. FROM 절 (인라인 뷰)
SELECT department, avg_sal
FROM (
SELECT department, AVG(salary) AS avg_sal
FROM employees
GROUP BY department
) AS dept_avg
WHERE avg_sal > 5000;
-- 3. SELECT 절 (스칼라 서브쿼리)
SELECT name, salary,
(SELECT AVG(salary) FROM employees) AS company_avg
FROM employees;
2-3. CTE (Common Table Expression)
정의: WITH 절로 정의하는 임시 가상 테이블 (쿼리 실행 중에만 존재)
기본 사용법
WITH dept_avg AS (
SELECT department, AVG(salary) AS avg_sal
FROM employees
GROUP BY department
)
SELECT e.name, e.salary, d.avg_sal
FROM employees e
JOIN dept_avg d ON e.department = d.department
WHERE e.salary > d.avg_sal;
여러 CTE 사용
WITH
sales_2023 AS (
SELECT product_id, SUM(amount) AS total
FROM sales
WHERE YEAR(sale_date) = 2023
GROUP BY product_id
),
top_products AS (
SELECT product_id
FROM sales_2023
WHERE total > 100000
)
SELECT p.name, s.total
FROM products p
JOIN top_products tp ON p.id = tp.product_id
JOIN sales_2023 s ON p.id = s.product_id;
3. 헷갈리는 개념 정리
3-1. VIEW vs CTE vs 인라인 뷰
| 구분 | VIEW | CTE | 인라인 뷰 |
|---|---|---|---|
| 문법 | CREATE VIEW |
WITH 절 |
FROM 절 서브쿼리 |
| 저장 | ✅ DB에 영구 저장 | ❌ 쿼리 실행 중만 | ❌ 쿼리 실행 중만 |
| 재사용 | 여러 쿼리에서 가능 | 해당 쿼리만 | 해당 쿼리만 |
| 가독성 | 보통 | ⭐ 높음 | 낮음 (중첩 시) |
사용 시기
- VIEW: 자주 사용하는 복잡한 쿼리를 저장
- CTE: 복잡한 쿼리를 단계별로 분리 (가독성 ↑)
- 인라인 뷰: 간단한 일회성 서브쿼리 (CTE 추천)
3-2. 집계 함수 vs 윈도우 함수
-- 집계 함수 (GROUP BY) → 행이 줄어듦
SELECT department, AVG(salary)
FROM employees
GROUP BY department;
-- 결과: 부서 수만큼의 행
-- 윈도우 함수 → 행 유지
SELECT name, department, salary,
AVG(salary) OVER(PARTITION BY department) AS dept_avg
FROM employees;
-- 결과: 전체 직원 수만큼의 행
3-3. WHERE vs HAVING
-- WHERE: 그룹화 전 필터링
SELECT department, AVG(salary)
FROM employees
WHERE age > 30 -- 개별 행 조건
GROUP BY department;
-- HAVING: 그룹화 후 필터링
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 5000; -- 그룹 조건
3-4. 비상관 서브쿼리 vs 상관 서브쿼리
-- 비상관 (1번만 실행)
SELECT name FROM employees
WHERE car_id IN (
SELECT car_id FROM rentals -- 한 번만 실행
WHERE status = 'active'
);
-- 상관 (각 행마다 실행)
SELECT name FROM employees e1
WHERE salary > (
SELECT AVG(salary) FROM employees e2
WHERE e2.department = e1.department -- 메인 쿼리 참조
);
⬇️ SQL 문법 정리.pdf 다운받기 ⬇️
SQL 문법 정리(MySQL).pdf
1.78MB
마무리
- SQL 학습의 핵심은 실행 순서를 이해하고, 각 절의 제약사항을 파악하는 것!
- 복잡한 쿼리는 CTE로 단계별로 분리하면 가독성과 유지보수성이 크게 향상된다!
'자격증 공부 > PCSQL' 카테고리의 다른 글
| [PCSQL] 문자열 추출 함수 정리 (0) | 2025.10.17 |
|---|---|
| [PCSQL] 우유와 요거트가 담긴 장바구니 (MySQL) (0) | 2025.10.15 |
| [PCSQL] 프로그래머스 - 대장균들의 자식의 수 구하기(MySQL) (0) | 2025.10.09 |
| [PCSQL] SELECT 쿼리 작성순서와 실행순서는 다르다. (0) | 2025.10.08 |
| [PCSQL] DATE_FORMAT 날짜 포맷 (0) | 2025.10.04 |