GROUP BY, HAVING, COUNT, SUM, AVG... 익숙하지만 제대로 알고 계신가요? 실무 데이터 분석에 꼭 필요한 집계 함수 활용법을 예제와 함께 쉽게 배워보세요! 📊
SQL 왕초보 가이드 - 2단계: 다중 테이블 조인과 실전 연습! 🎯
📢 SQL이 점점 재밌어지죠?
여러분, JOIN을 배워보니 SQL이 조금 익숙해졌나요? 😊
하지만 현실 데이터는 두 테이블에만 있는 게 아니죠!
이번에는 3개 이상의 테이블을 조인하는 방법과 자기 자신을 조인하는 SELF JOIN
, 그리고 집계 함수(GROUP BY
) 등을 실습해볼 거예요! 🚀
1️⃣ 다중 테이블 조인 (INNER JOIN
여러 번 사용)
👉 직원(employees
), 부서(departments
), 프로젝트(projects
)를 조인해볼까요?
✅ 목표:
- 직원(
employee_name
), 부서(department_name
), 프로젝트(project_name
) 정보를 가져오기
📌 예제 테이블 스키마
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
employee_name VARCHAR(50),
department_id INT
);
CREATE TABLE departments (
department_id INT PRIMARY KEY,
department_name VARCHAR(50)
);
CREATE TABLE projects (
project_id INT PRIMARY KEY,
project_name VARCHAR(50),
employee_id INT
);
📌 예제 데이터
INSERT INTO employees VALUES (1, 'Alice', 1), (2, 'Bob', 2), (3, 'Charlie', 3);
INSERT INTO departments VALUES (1, 'HR'), (2, 'IT'), (3, 'Sales');
INSERT INTO projects VALUES (1, 'Project A', 1), (2, 'Project B', 2);
📌 기대 결과
employee_name | department_name | project_name |
---|---|---|
Alice | HR | Project A |
Bob | IT | Project B |
📌 SQL 정답
SELECT employee_name, department_name, project_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN projects p ON e.employee_id = p.employee_id;
✅ 설명:
JOIN
을 2번 사용하여 3개의 테이블을 연결했어요!INNER JOIN
이므로 프로젝트가 없는 직원은 결과에서 제외됩니다.
📌 프로젝트가 없는 직원도 포함하려면?
SELECT employee_name, department_name, project_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id
LEFT JOIN projects p ON e.employee_id = p.employee_id;
📌 기대 결과 (모든 직원 포함)
employee_name | department_name | project_name |
---|---|---|
Alice | HR | Project A |
Bob | IT | Project B |
Charlie | Sales | NULL |
2️⃣ SELF JOIN
활용 - 직원 & 상사 정보 조회
👉 SELF JOIN
을 활용해 직원과 상사를 조회해볼까요?
✅ 목표:
- 각 직원(
employee_name
)과 해당 직원의 상사(manager_name
) 조회
📌 예제 테이블 스키마
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
employee_name VARCHAR(50),
department_id INT,
manager_id INT
);
📌 예제 데이터
INSERT INTO employees VALUES (1, 'Alice', 1, NULL), (2, 'Bob', 2, 1), (3, 'Charlie', 3, 1);
📌 기대 결과
employee_name | manager_name |
---|---|
Bob | Alice |
Charlie | Alice |
📌 SQL 정답
SELECT e1.employee_name, e2.employee_name AS manager_name
FROM employees e1
JOIN employees e2
ON e1.manager_id = e2.employee_id;
✅ 설명:
employees
테이블을 자기 자신과JOIN
하여 직원과 상사를 연결했어요.
📌 모든 직원(상사가 없는 직원 포함)을 출력하려면?
SELECT e1.employee_name, e2.employee_name AS manager_name
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;
📌 기대 결과 (모든 직원 포함)
employee_name | manager_name |
---|---|
Alice | NULL |
Bob | Alice |
Charlie | Alice |
3️⃣ GROUP BY
활용 - 각 부서별 직원 수 조회
👉 부서별로 직원이 몇 명인지 세볼까요?
📌 기대 결과
department_name | employee_count |
---|---|
HR | 1 |
IT | 1 |
Sales | 1 |
📌 SQL 정답
SELECT d.department_name, COUNT(*) AS employee_count
FROM employees e
JOIN departments d ON e.department_id = d.department_id
GROUP BY d.department_name;
✅ 설명:
GROUP BY
를 사용하면 같은 부서에 속한 직원들을 하나로 묶고, 개수를 셀 수 있어요!
📌 직원이 없는 부서도 포함하려면?
SELECT d.department_name, COUNT(e.employee_id) AS employee_count
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_name;
📌 기대 결과 (직원이 없는 부서 포함)
department_name | employee_count |
---|---|
HR | 1 |
IT | 1 |
Sales | 1 |
Marketing | 0 |
💡 COUNT(*) vs COUNT(컬럼명)의 차이
COUNT() 함수 | NULL 값 포함 여부 | 설명 |
---|---|---|
COUNT(*) |
✅ 포함 | 테이블의 모든 행을 계산 (NULL 값도 포함됨) |
COUNT(컬럼명) |
❌ 제외 | 해당 컬럼이 NULL이 아닌 행만 계산 |
4️⃣ HAVING
활용 - 직원이 2명 이상인 부서만 조회
👉 직원이 2명 이상인 부서만 조회해볼까요?
📌 예제 데이터
INSERT INTO employees VALUES (4, 'David', 1);
📌 기대 결과
department_name | employee_count |
---|---|
HR | 2 |
📌 SQL 정답
SELECT d.department_name, COUNT(*) AS employee_count
FROM departments d
JOIN employees e ON e.department_id = d.department_id
GROUP BY d.department_name
HAVING COUNT(*) >= 2;
✅ 설명:
HAVING COUNT(*) >= 2
를 사용하여 직원이 2명 이상인 부서만 필터링합니다.
📌 직원이 없는 부서까지 포함하고 직원이 2명 이상인 부서만 필터링하려면?
예제 상황이 다소 엉뚱할 수 있지만, SQL 동작 방식을 쉽게 이해하기 위한 설정이니 참고해주세요! 😆🚀
SELECT d.department_name, COUNT(e.employee_id) AS employee_count
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_name
HAVING COUNT(e.employee_id) >= 2;
💡두 쿼리의 차이점 정리
차이점 | 첫 번째 쿼리 (JOIN + COUNT(*)) | 두 번째 쿼리 (LEFT JOIN + COUNT(e.employee_id)) |
---|---|---|
직원이 없는 부서 포함 여부 | 아예 제외됨 | 포함됨 (NULL 로 표시됨) |
COUNT() 방식 | COUNT(*) (NULL 포함) |
COUNT(e.employee_id) (NULL 제외) |
최종 결과에서 직원 없는 부서 (Marketing ) |
애초에 JOIN 에서 제외됨 |
0 이지만 HAVING에서 제거됨 |
성능 | ✅ 빠름 | ❌ 느림 (불필요한 NULL 값 처리 필요) |
🎯 2단계 마무리!
오늘 배운 개념들 정리해볼까요? 🚀
✅ 다중 테이블 조인 (INNER JOIN
여러 번 사용)
✅ SELF JOIN
을 활용한 직원 & 상사 관계 조회
✅ GROUP BY
를 활용한 부서별 직원 수 집계
✅ HAVING
을 활용한 조건 필터링
📌 다음 단계에서는 SQL 최적화 및 성능 향상 기법을 다룰 예정이에요!
SQL을 더 빠르고 효율적으로 사용하는 법, 궁금하지 않나요? 😆
관련 시리즈 몰아보기
[SQL 01] JOIN 쉽게 이해하기 | 초보자를 위한 SQL 기초 강좌 📊
[SQL 03-1] 서브쿼리 최적화 | 성능을 10배 높이는 실전 가이드 🚀
'SQL 왕초보 가이드' 카테고리의 다른 글
[SQL 03-2] SQL 윈도우 함수 완벽 정리! 🚀 초보도 쉽게 배우는 순위 & 누적 합계 계산법! (0) | 2025.02.10 |
---|---|
[SQL 03-1] 서브쿼리 최적화 | 성능을 10배 높이는 실전 가이드 🚀 (0) | 2025.02.06 |
[SQL 01] JOIN 쉽게 이해하기 | 초보자를 위한 SQL 기초 강좌 📊 (0) | 2025.02.06 |