CodeGym /행동 /SQL SELF /JOIN 사용할 때 흔히 하는 실수들

JOIN 사용할 때 흔히 하는 실수들

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

이제 인생 얘기 좀 해볼까 해. 피할 수 없는 그 부분, 바로 실수! 실수를 잡고, 고치고, 이해하는 건 데이터 다룰 때 필수야. JOIN 쓸 때 어떤 함정이 있는지, 그리고 그걸 어떻게 피할 수 있는지 같이 보자.

실수 1: 조인 조건 빼먹기 — 데카르트 곱 만들기

가장 흔한 실수는 ON으로 조인 조건을 안 쓰는 거야. 이러면 데카르트 곱이 생기는데, 첫 번째 테이블의 모든 행이 두 번째 테이블의 모든 행과 조인돼. 결과적으로 엄청나게 많은 행이 나오고, 전혀 의미 없는 데이터만 잔뜩 생겨서 헷갈리게 돼.

예시를 들어볼게. 예를 들어, 이런 테이블이 있다고 하자:

학생들 (students):

student_id name
1 Otto
2 Anna

강의들 (courses):

course_id course_name
101 수학
102 역사

이제 ON을 빼먹고 쿼리를 작성해보자:

SELECT *
FROM students
JOIN courses;

결과:

student_id name course_id course_name
1 Otto 101 수학
1 Otto 102 역사
2 Anna 101 수학
2 Anna 102 역사

이거 진짜 말도 안 되지? 이 악몽이 바로 데카르트 곱이야.

해결법: ON을 써서 테이블이 어떻게 연결되는지 꼭 명시해줘.

SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;

그리고 여기서 또 다른 실수의 장이 열리지...

바보 방지 장치

이게 너무 흔한 문제라서 PostgreSQL에서는 ON과 조건 없이 JOIN 쓰는 걸 막아놨어.

만약 진짜로 모든 행을 다 조인하고 싶으면, JOIN 없이 이렇게 쓸 수 있어:

SELECT *
FROM students, courses;

또 다른 3번째 방법 - JOINON 없이 동작하는 경우:

  • NATURAL JOIN — 이름이 같은 컬럼을 자동으로 찾아서 조인해줘.
  • USING — 조인할 컬럼 리스트를 직접 지정할 수 있어.
  • CROSS JOIN — 항상 조건 없이, 즉 데카르트 곱이랑 똑같아.

실수 2: 잘못된 조인 조건

가끔 조인 조건을 쓰긴 쓰는데, 잘못 쓰는 경우가 있어. 예를 들어, 키가 아닌 관련 없는 데이터로 테이블을 조인하는 거지.

예를 들어, 학생과 그들이 수강하는 강의 목록을 얻고 싶은데, 실수로 관련 없는 필드로 조인하는 경우:

SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;

이런 쿼리는 잘못된 결과를 내. student_idcourse_id는 완전히 다른 거니까.

해결법: 조인할 때 올바른 컬럼을 쓰는지 꼭 확인해. 제대로 된 조인은 (학생과 강의를 연결하는 enrollments 테이블이 있다고 가정하면) 이렇게 쓸 수 있어:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

실수 3: 결과에 행이 중복됨

여러 개의 JOIN을 쿼리에 추가하면, 가끔 행이 중복돼서 나올 수 있어. JOIN하는 테이블에 중복된 데이터가 있거나, 조인 조건을 잘못 썼을 때 이런 일이 생겨.

예를 들어, Otto라는 학생이 enrollments 테이블에서 같은 강의에 두 번 등록되어 있다고 해보자.

enrollments의 데이터:

student_id course_id
1 101
1 101

이제 JOIN 쿼리를 돌리면 결과가 이렇게 나와:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

결과:

name course_name
Otto 수학
Otto 수학

해결법: 첫째, 테이블에 중복 데이터가 없는지 확인해. 둘째, 만약 이런 결과가 의도된 거라면 DISTINCT로 중복을 제거할 수 있어:

SELECT DISTINCT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

실수 4: INNER JOIN 쓸 때 행이 사라짐

INNER JOIN은 두 테이블 모두에 값이 있는 행만 반환해. 한쪽 테이블에 값이 없으면 그 행은 결과에서 빠져. 조인 타입을 잘못 고르면 데이터가 사라질 수 있어.

예를 들어, 아직 아무 강의도 듣지 않는 학생이 있다고 해보자:

학생들 (students):

student_id name
1 Otto
2 Anna
3 Dhany

등록 (enrollments):

student_id course_id
1 101
2 102

이제 INNER JOIN 쿼리를 돌리면:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

결과:

name course_name
Otto 수학
Anna 역사

근데 Dhany는 어디 갔지? 강의가 없는 학생도 포함하고 싶으면 LEFT JOIN을 써야 해:

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id;

실수 5: NULL 값 처리 실수

테이블에 NULL 값이 있으면, (예를 들어 필터링 조건을 쓸 때) 결과에서 빠질 수 있어.

예시: LEFT JOIN을 썼는데, 그 다음에 WHERE로 필터링을 추가한 경우.

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.course_name = '수학';

이제 강의가 없는 학생들은 결과에 안 나와, LEFT JOIN을 썼어도 말이야.

해결법: 강의가 없는 학생도 포함하고 싶으면 WHERE 대신 ON을 쓰거나, 조건을 추가해줘:

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.course_name IS NULL OR courses.course_name = '수학';

실수 6: 조인 타입 헷갈리기

어떤 조인 타입을 써야 할지 헷갈릴 때가 있어. 예를 들어, RIGHT JOIN을 쓰는데, 사실 LEFT JOIN에 테이블 순서만 바꿔도 되는 경우가 많아.

헷갈리지 않는 팁:

  • 가능하면 LEFT JOIN을 써. 이게 더 직관적이야.
  • 테이블 순서를 바꿔서 RIGHT JOIN을 안 써도 되게 해.
1
설문조사/퀴즈
다중 JOIN, 레벨 12, 레슨 4
사용 불가능
다중 JOIN
다중 JOIN
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION