sql 코딩테스트를 접하다 보면, 꼭 나오는 주제는 join입니다. 이 시리즈는 inner join과 outer join에 대해서 알아볼 거에요. 이 시리즈를 보기 전에 from 절과 카티션 곱에 대한 이해가 필요하니, 아직 이해를 못 하셨다면, 이 글을 보고 오시면 좋겠습니다.
- inner join [현재글]
- outer join
그러면, 1번째로 sql inner join에 대해 다뤄보겠습니다.
1개의 inner join
inner join은 두 테이블을 join 할 때, 두 테이블 모두에 지정한 열의 데이터가 있어야 합니다. 이것이 무슨 이야기인지는 outer join 시간에 다시 언급하겠습니다. 실습 재료로 돛단배 책에서 데이터를 import 하였습니다. 필요하다면, 여기에 들어가셔서 import 하시면 되겠습니다.
먼저, instructor와 department를 보겠습니다. instructor는 교수를 의미합니다. 그리고, department는 학부를 의미합니다. 예를 들어 컴퓨터 학부, 경제 학부와 같은 것들입니다. 제약 조건은 아래와 같다고 해 보겠습니다.
- 교수는 하나의 학부에 속합니다.
- 교수의 연구실은 학부가 있는 건물에 있습니다.
예를 들어, 경제 학부 교수인 경우, 경제 학부가 있는 건물에 연구실이 있는 셈입니다. 이 때, 우리는 아래의 요구 사항을 처리하고 싶어요.
- 교수의 id와 이름, 학부를 얻고 싶어요.
- 그런데 교수의 연구실이 있는 건물도 같이 얻고 싶습니다.
이럴 때 어떻게 해야 할까요? 이럴 때, inner join을 쓸 수 있습니다.
from A inner join B on condition
A와 B를 condition 조건을 만족하는 경우 join 한다.
하나씩 천천히 봅시다.
교수 테이블에는 id와 이름, dept_name과 salary 정도만 있어요. 학부 dept_name이 속해있는 건물에 대한 정보는 어디에도 없어요. department 테이블을 봅시다.
department 테이블을 보니까, 학부가 있는 건물에 대한 정보가 있습니다. Civil Eng.는 Chandler 빌딩에 있네요. 이 두 테이블에서 결과를 얻어와야 해요.
이 경우, instructor의 depth_name과, department의 dept_name이 같으면 얻어오면 됩니다. 이를 조건절에 넣어주면 되겠지요.
우리는 instructor에서 id, name, dept_name을 얻고, department에서 building을 얻으면 됩니다. from 절을 봅시다. instructor와 department를 inner join을 하였습니다. 뒤에 on 절을 볼까요?
instructor.dept_name = department.dept_name
instructor의 dept_name과, department의 dept_name이 같으면 join
그러면 아래의 경우는 어떻게 될까요?
on 절에 instructor.dept_name = department.dept_name이 온 경우 어떤가요? 이 경우, join이 안 됩니다. 왜냐하면, Civil Eng.와 Computer는 다르기 때문입니다.
sql inner join 여러개
셋 이상의 테이블에서 정보를 가지고 와야 할 경우도 있습니다.
ER 다이어 그램을 보면, 전형적인 mapping이 들어가 있음을 볼 수 있어요. 교수가 어떤 학생을 상담하는지 저장되어 있는 것이 advisor입니다. 요구 사항은 간단합니다.
- 상담 교수의 이름과 학생의 이름을 가져오세요.
어떻게 해야 할까요? 일단, 저 세 테이블에서 가져와야 함은 명확해 보이는데요. base table부터 잡아봅시다. advisor에 어떤 교수가 어떤 학생을 상담하는지가 있으니, 이를 base로 잡아 볼게요.
우리는 여기서 id가 24746인 학생의 name과, id가 19368인 교수의 name을 얻고 싶습니다. 그러면 먼저, advisor 테이블과 학생 테이블에 대해 join을 해야 겠지요?
고로, 쿼리를 아래와 같이 작성하면 됩니다.
보면, advisor라는 테이블에서, student와 inner join을 했습니다. 조건이 어떻게 되나요?
student.id = advisor.s_id
student의 id와 advisor의 s_id가 같으면 join 합니다.
그리고 나서, select에서 student.name과 advisor의 i_id만 얻어온 것이지요. 상담 교수의 이름까지 얻어오려면 어떻게 해야 할까요?
또 inner join을 하면 됩니다. instructor와요. 조인 조건은 어떻게 하면 될까요?
- advisor의 i_id와, instructor의 id가 같으면 됩니다.
따라서, 쿼리는 아래와 같습니다.
보면, advisor를 base로 잡아서, student와 1차 조인을, instructor와 2차 조인을 했음을 볼 수 있습니다.