SQL JOIN 예제 상세 해설
이 문서는 join_examples.sql 파일의 각 예제에 대한 상세한 설명과 실행 결과를 제공합니다.
목차
INNER JOIN 예제
예제 1-1: 기본 INNER JOIN
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
g.subject AS 과목,
g.score AS 점수
FROM student s
INNER JOIN grade g ON s.student_no = g.student_no;
설명:
- 목적: 학생 테이블과 성적 테이블을 조인하여 학생 이름, 전공, 과목, 점수를 함께 조회
- 조인 조건:
s.student_no = g.student_no(학번으로 연결) - INNER JOIN 특징: 두 테이블 모두에 존재하는 데이터만 반환 (교집합)
예상 결과:
학생이름 | 전공 | 과목 | 점수
---------|------------|-------------------|------
김철수 | 컴퓨터공학 | 데이터베이스 | 85
김철수 | 컴퓨터공학 | 자바프로그래밍 | 90
이영희 | 경영학 | 경영정보시스템 | 88
이영희 | 경영학 | 회계원리 | 92
박민수 | 컴퓨터공학 | 데이터베이스 | 78핵심 포인트:
student테이블의 모든 학생이 포함되지 않음 (성적이 없는 학생 제외)grade테이블의S006학생 성적도 제외됨 (학생 테이블에 없음)- 총 5행 반환 (S001 2개, S002 2개, S003 1개)
예제 1-2: 특정 전공 학생의 성적만 조회
SQL 코드:
SELECT
s.name AS 학생이름,
g.subject AS 과목,
g.score AS 점수
FROM student s
INNER JOIN grade g ON s.student_no = g.student_no
WHERE s.major = '컴퓨터공학'
ORDER BY g.score DESC;
설명:
- 목적: 컴퓨터공학 전공 학생의 성적만 조회하고 점수 높은 순으로 정렬
- WHERE 절: 전공이 '컴퓨터공학'인 학생만 필터링
- ORDER BY: 점수를 내림차순으로 정렬
예상 결과:
학생이름 | 과목 | 점수
---------|-------------------|------
김철수 | 자바프로그래밍 | 90
김철수 | 데이터베이스 | 85
박민수 | 데이터베이스 | 78핵심 포인트:
- WHERE 절은 JOIN 이후에 적용됨
- ORDER BY로 결과 정렬 가능
- INNER JOIN + WHERE로 원하는 데이터만 추출
예제 1-3: 3개 테이블 JOIN
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
d.dept_name AS 부서명,
d.location AS 위치,
g.subject AS 과목,
g.score AS 점수
FROM student s
INNER JOIN grade g ON s.student_no = g.student_no
INNER JOIN department d ON s.major = d.dept_name;
설명:
- 목적: 학생, 성적, 부서 정보를 모두 조인하여 상세 정보 조회
- 조인 순서:
student와grade조인- 결과와
department조인
- 조인 조건:
- 첫 번째:
s.student_no = g.student_no(학번) - 두 번째:
s.major = d.dept_name(전공 = 부서명)
- 첫 번째:
예상 결과:
학생이름 | 전공 | 부서명 | 위치 | 과목 | 점수
---------|------------|------------|-------|-------------------|------
김철수 | 컴퓨터공학 | 컴퓨터공학 | 1호관 | 데이터베이스 | 85
김철수 | 컴퓨터공학 | 컴퓨터공학 | 1호관 | 자바프로그래밍 | 90
이영희 | 경영학 | 경영학 | 2호관 | 경영정보시스템 | 88
이영희 | 경영학 | 경영학 | 2호관 | 회계원리 | 92
박민수 | 컴퓨터공학 | 컴퓨터공학 | 1호관 | 데이터베이스 | 78핵심 포인트:
- 여러 테이블을 연속으로 조인 가능
- 각 조인마다 조건을 지정해야 함
- 모든 조인 조건을 만족하는 데이터만 반환
LEFT JOIN 예제
예제 2-1: 기본 LEFT JOIN
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
g.subject AS 과목,
g.score AS 점수
FROM student s
LEFT JOIN grade g ON s.student_no = g.student_no;
설명:
- 목적: 모든 학생을 조회하고, 성적이 있으면 함께 표시
- LEFT JOIN 특징: 왼쪽 테이블(
student)의 모든 행 포함 - NULL 처리: 성적이 없는 학생의 과목과 점수는 NULL로 표시
예상 결과:
학생이름 | 전공 | 과목 | 점수
---------|------------|-------------------|------
김철수 | 컴퓨터공학 | 데이터베이스 | 85
김철수 | 컴퓨터공학 | 자바프로그래밍 | 90
이영희 | 경영학 | 경영정보시스템 | 88
이영희 | 경영학 | 회계원리 | 92
박민수 | 컴퓨터공학 | 데이터베이스 | 78
최지영 | 영어영문 | NULL | NULL핵심 포인트:
student테이블의 모든 학생이 포함됨 (4명)- 성적이 없는 학생(
최지영)도 NULL로 표시되어 포함됨 - 총 6행 반환 (성적 있는 학생 5행 + 성적 없는 학생 1행)
예제 2-2: 성적이 없는 학생 찾기
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
s.grade AS 학년
FROM student s
LEFT JOIN grade g ON s.student_no = g.student_no
WHERE g.student_no IS NULL;
설명:
- 목적: 성적이 없는 학생을 찾아 출력
- WHERE 조건:
g.student_no IS NULL- 조인된 성적 테이블의 학번이 NULL인 경우 - 실전 활용: 데이터 정합성 확인, 미입력 데이터 찾기
예상 결과:
학생이름 | 전공 | 학년
---------|--------|-----
최지영 | 영어영문| 3핵심 포인트:
- LEFT JOIN 후 WHERE 절로 NULL 값 필터링
IS NULL사용 (등호=사용 불가)- 데이터 검증 및 관리에 유용
예제 2-3: 집계 함수와 함께 사용
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
AVG(g.score) AS 평균점수,
COUNT(g.score) AS 과목수
FROM student s
LEFT JOIN grade g ON s.student_no = g.student_no
GROUP BY s.student_no, s.name, s.major;
설명:
- 목적: 각 학생의 평균 점수와 과목 수를 계산 (성적이 없는 학생도 포함)
- 집계 함수:
AVG(g.score): 평균 점수 계산COUNT(g.score): NULL이 아닌 점수 개수만 카운트
- GROUP BY: 학생별로 그룹화
예상 결과:
학생이름 | 전공 | 평균점수 | 과목수
---------|------------|----------|-------
김철수 | 컴퓨터공학 | 87.5000 | 2
이영희 | 경영학 | 90.0000 | 2
박민수 | 컴퓨터공학 | 78.0000 | 1
최지영 | 영어영문 | NULL | 0핵심 포인트:
- LEFT JOIN으로 모든 학생 포함
COUNT(g.score)는 NULL을 제외하고 카운트AVG(g.score)는 NULL이 있으면 NULL 반환- 성적이 없는 학생도 결과에 포함됨
RIGHT JOIN 예제
예제 3-1: 기본 RIGHT JOIN
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
g.subject AS 과목,
g.score AS 점수
FROM student s
RIGHT JOIN grade g ON s.student_no = g.student_no;
설명:
- 목적: 모든 성적을 조회하고, 학생 정보가 있으면 함께 표시
- RIGHT JOIN 특징: 오른쪽 테이블(
grade)의 모든 행 포함 - NULL 처리: 학생 정보가 없는 성적의 학생 이름과 전공은 NULL로 표시
예상 결과:
학생이름 | 전공 | 과목 | 점수
---------|------------|-------------------|------
김철수 | 컴퓨터공학 | 데이터베이스 | 85
김철수 | 컴퓨터공학 | 자바프로그래밍 | 90
이영희 | 경영학 | 경영정보시스템 | 88
이영희 | 경영학 | 회계원리 | 92
박민수 | 컴퓨터공학 | 데이터베이스 | 78
NULL | NULL | 네트워크 | 95핵심 포인트:
grade테이블의 모든 성적이 포함됨 (6개)- 학생 정보가 없는 성적(
S006의 네트워크)도 NULL로 표시되어 포함됨 - 총 6행 반환
예제 3-2: 학생 정보가 없는 성적 찾기
SQL 코드:
SELECT
g.student_no AS 학번,
g.subject AS 과목,
g.score AS 점수
FROM student s
RIGHT JOIN grade g ON s.student_no = g.student_no
WHERE s.student_no IS NULL;
설명:
- 목적: 학생 정보가 없는 성적을 찾아 출력
- WHERE 조건:
s.student_no IS NULL- 조인된 학생 테이블의 학번이 NULL인 경우 - 실전 활용: 데이터 정합성 확인, 고아 레코드(Orphan Record) 찾기
예상 결과:
학번 | 과목 | 점수
-----|----------|------
S006 | 네트워크 | 95핵심 포인트:
- RIGHT JOIN 후 WHERE 절로 NULL 값 필터링
- 데이터 무결성 검증에 유용
- 참조 무결성 위반 데이터 찾기
FULL OUTER JOIN 예제
예제 4-1: FULL OUTER JOIN 구현
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
g.subject AS 과목,
g.score AS 점수
FROM student s
LEFT JOIN grade g ON s.student_no = g.student_no
UNION
SELECT
s.name AS 학생이름,
s.major AS 전공,
g.subject AS 과목,
g.score AS 점수
FROM student s
RIGHT JOIN grade g ON s.student_no = g.student_no;
설명:
- 목적: 양쪽 테이블의 모든 데이터를 포함 (합집합)
- MySQL 제한: FULL OUTER JOIN을 직접 지원하지 않아 UNION으로 구현
- UNION: 중복 제거 (UNION ALL은 중복 포함)
예상 결과:
학생이름 | 전공 | 과목 | 점수
---------|------------|-------------------|------
김철수 | 컴퓨터공학 | 데이터베이스 | 85
김철수 | 컴퓨터공학 | 자바프로그래밍 | 90
이영희 | 경영학 | 경영정보시스템 | 88
이영희 | 경영학 | 회계원리 | 92
박민수 | 컴퓨터공학 | 데이터베이스 | 78
최지영 | 영어영문 | NULL | NULL
NULL | NULL | 네트워크 | 95핵심 포인트:
- LEFT JOIN과 RIGHT JOIN을 UNION으로 결합
- 양쪽 테이블의 모든 데이터 포함
- 중복 행은 자동 제거됨 (UNION의 특징)
CROSS JOIN 예제
예제 5-1: 학생과 부서의 모든 조합
SQL 코드:
SELECT
s.name AS 학생이름,
d.dept_name AS 부서명,
d.location AS 위치
FROM student s
CROSS JOIN department d;
설명:
- 목적: 학생과 부서의 모든 가능한 조합 생성
- CROSS JOIN 특징: 조건 없이 모든 조합 생성 (카티션 곱)
- 결과 행 수: 학생 수 × 부서 수 = 4명 × 4개 부서 = 16행
예상 결과:
학생이름 | 부서명 | 위치
---------|------------|------
김철수 | 컴퓨터공학 | 1호관
김철수 | 경영학 | 2호관
김철수 | 영어영문 | 3호관
김철수 | 수학 | 4호관
이영희 | 컴퓨터공학 | 1호관
이영희 | 경영학 | 2호관
이영희 | 영어영문 | 3호관
이영희 | 수학 | 4호관
박민수 | 컴퓨터공학 | 1호관
박민수 | 경영학 | 2호관
박민수 | 영어영문 | 3호관
박민수 | 수학 | 4호관
최지영 | 컴퓨터공학 | 1호관
최지영 | 경영학 | 2호관
최지영 | 영어영문 | 3호관
최지영 | 수학 | 4호관핵심 포인트:
- 조건 없이 모든 조합 생성
- 결과가 매우 많아질 수 있음 (주의 필요)
- 실무에서는 거의 사용하지 않음
- 특별한 경우(조합 생성, 테스트 데이터 등)에만 사용
SELF JOIN 예제
예제 6-1: 직원과 상사 정보 조회
SQL 코드:
SELECT
e1.emp_name AS 직원이름,
e2.emp_name AS 상사이름
FROM employee e1
LEFT JOIN employee e2 ON e1.manager_id = e2.emp_id;
설명:
- 목적: 각 직원과 그들의 상사 정보를 조회
- SELF JOIN: 같은 테이블을 두 번 조인
- 별칭 사용:
e1(직원),e2(상사)로 구분 - LEFT JOIN: 상사가 없는 직원(대표)도 포함
예상 결과:
직원이름 | 상사이름
---------|----------
김대표 | NULL
이부장 | 김대표
박과장 | 이부장
최대리 | 이부장
정사원 | 박과장핵심 포인트:
- 같은 테이블을 두 번 조인
- 별칭(alias)을 반드시 사용해야 함
- 계층 구조 데이터 처리에 유용
- 조직도, 카테고리 트리 등에 활용
예제 6-2: 같은 전공 학생 찾기
SQL 코드:
SELECT
s1.name AS 학생1,
s2.name AS 학생2,
s1.major AS 전공
FROM student s1
INNER JOIN student s2 ON s1.major = s2.major
WHERE s1.student_id < s2.student_id;
설명:
- 목적: 같은 전공의 학생들을 쌍으로 조회
- 조인 조건:
s1.major = s2.major(같은 전공) - WHERE 조건:
s1.student_id < s2.student_id(중복 제거)- 예: (김철수, 박민수)와 (박민수, 김철수) 중 하나만 선택
예상 결과:
학생1 | 학생2 | 전공
------|------|----------
김철수 | 박민수 | 컴퓨터공학핵심 포인트:
- 같은 테이블 내의 관계 찾기
- WHERE 절로 중복 제거
- 조합(Combination) 생성에 유용
실전 예제
예제 7-1: 학생별 총점과 평균
SQL 코드:
SELECT
s.name AS 학생이름,
s.major AS 전공,
COUNT(g.subject) AS 과목수,
SUM(g.score) AS 총점,
AVG(g.score) AS 평균점수
FROM student s
LEFT JOIN grade g ON s.student_no = g.student_no
GROUP BY s.student_no, s.name, s.major
ORDER BY 평균점수 DESC;
설명:
- 목적: 각 학생의 과목 수, 총점, 평균 점수를 계산
- LEFT JOIN: 성적이 없는 학생도 포함
- 집계 함수: COUNT, SUM, AVG 사용
- GROUP BY: 학생별로 그룹화
- ORDER BY: 평균 점수 높은 순으로 정렬
예상 결과:
학생이름 | 전공 | 과목수 | 총점 | 평균점수
---------|------------|--------|------|----------
이영희 | 경영학 | 2 | 180 | 90.0000
김철수 | 컴퓨터공학 | 2 | 175 | 87.5000
박민수 | 컴퓨터공학 | 1 | 78 | 78.0000
최지영 | 영어영문 | 0 | NULL | NULL핵심 포인트:
- LEFT JOIN으로 모든 학생 포함
- 집계 함수와 GROUP BY 함께 사용
- ORDER BY로 결과 정렬
- 실전에서 가장 많이 사용되는 패턴
예제 7-2: 전공별 평균 점수
SQL 코드:
SELECT
s.major AS 전공,
COUNT(DISTINCT s.student_no) AS 학생수,
COUNT(g.subject) AS 과목수,
AVG(g.score) AS 전공평균점수
FROM student s
LEFT JOIN grade g ON s.student_no = g.student_no
GROUP BY s.major
ORDER BY 전공평균점수 DESC;
설명:
- 목적: 전공별로 학생 수, 과목 수, 평균 점수를 계산
- COUNT(DISTINCT): 중복 제거하여 학생 수 계산
- COUNT(g.subject): 과목 수 계산 (NULL 제외)
- GROUP BY: 전공별로 그룹화
예상 결과:
전공 | 학생수 | 과목수 | 전공평균점수
------------|--------|--------|-------------
경영학 | 1 | 2 | 90.0000
컴퓨터공학 | 2 | 3 | 83.3333
영어영문 | 1 | 0 | NULL핵심 포인트:
- 전공별 집계
- COUNT(DISTINCT)로 중복 제거
- 그룹별 통계 계산
예제 7-3: 복잡한 JOIN (3개 이상 테이블)
SQL 코드:
SELECT
s.student_no AS 학번,
s.name AS 학생이름,
s.major AS 전공,
d.location AS 부서위치,
g.subject AS 과목,
g.score AS 점수,
CASE
WHEN g.score >= 90 THEN 'A'
WHEN g.score >= 80 THEN 'B'
WHEN g.score >= 70 THEN 'C'
ELSE 'F'
END AS 등급
FROM student s
INNER JOIN grade g ON s.student_no = g.student_no
LEFT JOIN department d ON s.major = d.dept_name
ORDER BY s.name, g.score DESC;
설명:
- 목적: 학생, 성적, 부서 정보를 모두 조인하고 등급 계산
- 조인 순서:
student와gradeINNER JOIN- 결과와
departmentLEFT JOIN
- CASE 문: 점수에 따라 등급 부여
- ORDER BY: 학생 이름 순, 같은 학생은 점수 높은 순
예상 결과:
학번 | 학생이름 | 전공 | 부서위치 | 과목 | 점수 | 등급
-----|---------|------------|---------|-------------------|------|-----
S001 | 김철수 | 컴퓨터공학 | 1호관 | 자바프로그래밍 | 90 | A
S001 | 김철수 | 컴퓨터공학 | 1호관 | 데이터베이스 | 85 | B
S002 | 이영희 | 경영학 | 2호관 | 회계원리 | 92 | A
S002 | 이영희 | 경영학 | 2호관 | 경영정보시스템 | 88 | B
S003 | 박민수 | 컴퓨터공학 | 1호관 | 데이터베이스 | 78 | C핵심 포인트:
- 여러 테이블 조인
- INNER JOIN과 LEFT JOIN 혼합 사용
- CASE 문으로 조건부 값 생성
- 복잡한 비즈니스 로직 구현
예제 7-4: 조건이 있는 JOIN
SQL 코드:
SELECT
s.name AS 학생이름,
g.subject AS 과목,
g.score AS 점수
FROM student s
INNER JOIN grade g ON s.student_no = g.student_no
AND g.score >= 80
ORDER BY g.score DESC;
설명:
- 목적: 80점 이상인 성적만 조인하여 조회
- 조인 조건 확장:
ON절에 추가 조건 포함 - WHERE vs ON:
ON절: 조인 시점에 필터링 (조인 전)WHERE절: 조인 후 필터링
- 성능: ON 절 조건이 더 효율적일 수 있음
예상 결과:
학생이름 | 과목 | 점수
---------|-------------------|------
이영희 | 회계원리 | 92
김철수 | 자바프로그래밍 | 90
이영희 | 경영정보시스템 | 88
김철수 | 데이터베이스 | 85핵심 포인트:
- ON 절에 조건 추가 가능
- 조인 시점에 필터링
- 성능 최적화에 유용
- WHERE 절과의 차이 이해
실행 방법
1. 테이블 생성 및 데이터 삽입
먼저 create_table.sql 파일을 실행하여 테이블과 데이터를 준비합니다.
mysql -u 사용자명 -p < create_table.sql
2. 예제 실행
join_examples.sql 파일의 원하는 예제만 선택하여 실행하거나, 전체를 실행할 수 있습니다.
mysql -u 사용자명 -p < join_examples.sql
또는 MySQL Workbench에서:
join_examples.sql파일 열기- 실행하고 싶은 예제만 선택
- 실행 (F9 또는 Ctrl+Shift+Enter)
학습 체크리스트
각 예제를 학습한 후 다음 사항을 확인하세요:
INNER JOIN
- 두 테이블의 교집합만 반환하는 것을 이해했는가?
- WHERE 절과 함께 사용할 수 있는가?
- 3개 이상 테이블을 조인할 수 있는가?
LEFT JOIN
- 왼쪽 테이블의 모든 행을 포함하는 것을 이해했는가?
- NULL 값으로 매칭되지 않는 데이터를 찾을 수 있는가?
- 집계 함수와 함께 사용할 수 있는가?
RIGHT JOIN
- 오른쪽 테이블의 모든 행을 포함하는 것을 이해했는가?
- LEFT JOIN과의 차이를 이해했는가?
FULL OUTER JOIN
- UNION을 사용하여 구현할 수 있는가?
- 양쪽 테이블의 모든 데이터를 포함하는 것을 이해했는가?
CROSS JOIN
- 모든 조합을 생성하는 것을 이해했는가?
- 언제 사용해야 하는지 알고 있는가?
SELF JOIN
- 같은 테이블을 두 번 조인할 수 있는가?
- 별칭을 사용하는 이유를 이해했는가?
실전 예제
- 집계 함수와 JOIN을 함께 사용할 수 있는가?
- 복잡한 조인을 작성할 수 있는가?
- ON 절에 조건을 추가할 수 있는가?
주의사항
1. NULL 값 처리
LEFT JOIN이나 RIGHT JOIN 사용 시 NULL 값이 발생할 수 있습니다. 집계 함수 사용 시 주의하세요.
-- COUNT(g.score)는 NULL을 제외하고 카운트
-- AVG(g.score)는 NULL이 있으면 NULL 반환
2. 성능 고려
- 큰 테이블 간 JOIN은 시간이 오래 걸릴 수 있음
- 인덱스를 적절히 사용
- 필요한 컬럼만 SELECT
3. 조인 순서
여러 테이블을 조인할 때 순서가 중요할 수 있습니다. 일반적으로 작은 테이블부터 조인하는 것이 효율적입니다.
요약
JOIN 선택 가이드
| 상황 | 사용할 JOIN |
|---|---|
| 두 테이블 모두에 있는 데이터만 필요 | INNER JOIN |
| 왼쪽 테이블 전체 + 매칭 데이터 | LEFT JOIN |
| 오른쪽 테이블 전체 + 매칭 데이터 | RIGHT JOIN |
| 양쪽 테이블 전체 | FULL OUTER JOIN (UNION) |
| 모든 조합 생성 | CROSS JOIN |
| 같은 테이블 내 관계 | SELF JOIN |
핵심 포인트
- INNER JOIN이 가장 많이 사용됨
- LEFT JOIN은 "모든 A와 매칭되는 B"를 조회할 때 사용
- JOIN 조건은 보통 외래키 관계를 사용
- 집계 함수와 함께 사용하면 강력함
- NULL 값 처리에 주의
이 설명서와 함께 JOIN을 마스터하세요!
'BackEnd > MySql' 카테고리의 다른 글
| 데이터 베이스 종합 실습 문제 - 도서관 시스템 (20문제) (0) | 2026.02.04 |
|---|---|
| SQL JOIN 실습용 테이블 생성 및 데이터 삽입 (0) | 2026.02.04 |
| SQL JOIN 예제 모음 (0) | 2026.02.04 |
| SQL 집계함수 실습 문제 정답 및 해설 (0) | 2026.02.03 |
| SQL 실습 문제 - member1 테이블 (정답 - 해설) (0) | 2026.01.30 |