CodeGym /행동 /SQL SELF /여러 개의 JOIN 한 쿼리에서 사용하기

여러 개의 JOIN 한 쿼리에서 사용하기

SQL SELF
레벨 12 , 레슨 1
사용 가능

각 테이블이 하나의 큰 퍼즐 조각이라고 생각해봐. 학생 테이블은 누가 공부하는지 알고 있고, 강좌 테이블은 무엇을 가르치는지 알려주고, 수강신청 테이블은 누가 어떤 강좌를 듣는지 보여줘. 근데 따로 보면 아무 의미 없어. 전체 그림을 보고 싶으면 이 조각들을 합쳐야 해 — 여기서 여러 개의 JOIN이 등장하는 거지.

실제로 데이터는 구조화와 중복 방지를 위해 연관된 테이블로 나눠져 있어. 예를 들어, 우리 대학 DB에는 이런 테이블들이 있어:

  • students — 학생 정보.
  • enrollments — 학생의 강좌 수강신청 정보.
  • courses — 강좌 정보.

학생, 강좌, 그리고 강사까지 전부 한 번에 보고 싶으면, 세 개의 테이블을 JOIN으로 합쳐야 해.

JOIN 실행 순서

여러 개의 JOIN을 쓸 때 PostgreSQL은 왼쪽에서 오른쪽 순서로 처리해. 즉, 먼저 앞의 두 테이블을 합치고, 그 결과를 세 번째 테이블과 합치는 식이야, 계속 반복.

예시:

SELECT *
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id;
  1. 먼저 studentsenrollmentsstudents.id = enrollments.student_id로 합쳐.
  2. 그 결과를 enrollments.course_id = courses.idcourses와 합쳐.

특히 테이블이 크면 실행 순서가 엄청 중요해. JOIN 구조가 잘못되면 성능이 확 떨어질 수 있어.

예시: 학생, 강좌, 강사 리스트

예를 들어, 이런 데이터 테이블이 있다고 해보자:

students 테이블:

id name
1 Otto Song
2 Maria Chi
3 Alex Lin

courses 테이블:

id name teacher
101 Mathematics Ellen Moore
102 Physics James Okoro
103 Computer Science Nina Delgado

enrollments 테이블:

student_id course_id
1 101
1 103
2 102
3 101

쿼리:

SELECT
    students.name AS student_name,
    courses.name AS course_name,
    courses.teacher AS teacher_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id;

결과:

student_name course_name teacher_name
Otto Song Mathematics Ellen Moore
Otto Song Computer Science Nina Delgado
Maria Chi Physics James Okoro
Alex Lin Mathematics Ellen Moore

여러 JOIN 쿼리에서 필터링

JOIN 쿼리에도 필터 조건을 걸 수 있어. 이렇게 하면 결과 데이터가 줄고 쿼리 속도도 빨라져. 예를 들어, "Mathematics" 강좌 듣는 학생만 보고 싶으면:

SELECT
    students.name AS student_name,
    courses.name AS course_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id
WHERE courses.name = 'Mathematics';

결과:

student_name course_name
Otto Song Mathematics
Alex Lin Mathematics

여러 JOIN 쿼리 최적화

테이블이 크면 쿼리 최적화가 진짜 중요해. 몇 가지 팁을 줄게:

  1. 인덱스 사용하기

인덱스 덕분에 PostgreSQL이 훨씬 빠르게 동작해, 특히 키 필드로 JOIN할 때. enrollments 테이블의 student_idcourse_id에 인덱스가 있는지 꼭 확인해.

인덱스 만드는 예시:

CREATE INDEX idx_enrollments_student_id ON enrollments(student_id);
CREATE INDEX idx_enrollments_course_id ON enrollments(course_id);

인덱스에 대해서는 다음 레벨에서 더 자세히 배울 거지만, 여기서도 언급하는 이유가 있어. JOIN이랑 엄청 자주 쓰이거든.

  1. 초반에 데이터 필터링하기

WHERE 조건을 써서 JOIN 전에 처리할 행 수를 줄여봐. 예시:

SELECT
    students.name AS student_name,
    courses.name AS course_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id
WHERE 
    courses.teacher = 'Ivan Petrov';
  1. 합칠 행 수 최소화하기

두 테이블의 모든 행을 합치지 말고, 먼저 서브쿼리로 필터링해봐:

SELECT
    students.name AS student_name,
    courses.name AS course_name
FROM 
    (SELECT * FROM students WHERE id IN (1, 2)) sub_students
INNER JOIN enrollments ON sub_students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id;

서브쿼리(중첩 SELECT)는 바로 다음 레벨에서 더 자세히 배울 거야 :P

복잡한 JOIN 예시: 학생, 강좌, 학부

이번엔 faculties라는 테이블이 하나 더 추가됐다고 해보자:

faculties 테이블:

id name
10 Engineering
20 Natural Sciences

courses 테이블이 이렇게 바뀜:

id name teacher faculty_id
101 Mathematics Ellen Moore 10
102 Physics James Okoro 20
103 Computer Science Nina Delgado 10

학생, 강좌, 학부까지 한 번에 보려면 JOIN을 하나 더 추가하면 돼:

SELECT
    students.name AS student_name,
    courses.name AS course_name,
    faculties.name AS faculty_name
FROM students
    INNER JOIN enrollments ON students.id = enrollments.student_id
    INNER JOIN courses ON enrollments.course_id = courses.id
    INNER JOIN faculties ON courses.faculty_id = faculties.id;

결과:

student_name course_name faculty_name
Otto Song Mathematics Engineering
Otto Song Computer Science Engineering
Maria Chi Physics Natural Sciences
Alex Lin Mathematics Engineering

여러 JOIN을 쓰는 SQL 쿼리는 좀 복잡할 수 있지만, 진짜 강력한 리포트와 인사이트를 뽑아낼 수 있어. 최적화랑 구조만 잘 잡으면 대용량 DB에서도 완전 유용한 무기가 될 거야.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION