일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 온디바이스AI
- CPU 스케줄링
- 운영체제와 정보기술의 원리
- 시그널 핸들러
- Extendable hashing
- 쉬운 코드
- concurrency control
- SDK
- 시스템프로그래밍
- recoverability
- B tree 데이터삽입
- 운영체제
- vite
- 백엔드
- 갤럭시 S24
- 반효경
- 커널 동기화
- Git
- 코딩테스트 [ ALL IN ONE ]
- 코딩애플
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- 데이터베이스
- 개발남노씨
- 쉬운코드
- SQL
- 네트워크
- 트랜잭션
- 인터럽트
- 프로세스 주소 공간
- 김영한
- Today
- Total
티끌모아 태산
SQL 데이터 조회: JOIN 본문
이번시간에는 SQL에서 JOIN의 의미와 종류 그리고 특징에 대해서 배운내용을 정리해보도록 하겠습니다.
JOIN
SQL에게 JOIN은 두 개 이상의 테이블들에 있는 데이터를 한번에 조회하는 것입니다. 그리고 이 JOIN은 여러 종류가 있습니다.
implicit join vs explicit join
- ID가 1인 임직원이 속한 부서 이름은?
SELECT D.name FROM employee AS E, department AS D
WHERE E.id = 1 AND E.dept_id = D.id;

이렇게 FROM절에는 테이블만 나열하고 WHERE절에 join condition을 명시하는 방식을 implicit 방식이라 합니다.

위 내용처럼 implicit join은 가독성과 잘못된 쿼리 작성 가능성 때문에 explicit join방식이 등장했습니다.
SELECT D.name FROM employee AS E JOIN department AS D ON E.dept_id = D.id
WHERE E.id = 1;

이런식으로 explicit join은 가독성과 쿼리 작성 실수 가능성 문제를 해결해 줍니다.
inner join vs outer join
inner join은 ⭐️두 테이블에서 join condition을 만족하는 튜플들로 result table을 만드는 join이다. 아래 예시를 살펴보면, employee테이블에서 SIMON은 dept_id 가 NULL이고 department 테이블에서도 HR속한 임직원이 아무도없기 때문에 결과 테이블에서는 볼 수없음을 확인할 수 있습니다. 그리고 inner join은 보통 우리가 사용하는 join앞에 생략되기 때문에 이미 inner join을 사용했다고 생각하시면 됩니다.
SELECT * FROM employee E INNER JOIN department D ON E.dept_id = D.id;


join codition을 만족하지 못하는 ❗️SIMON과 HR부서는 결과 테이블에 포함되지 않는 것을 확인할 수 있습니다.

그 다음으로 ⭐️outer join은 두 테이블에서 join condition을 만족하지 않는 튜플들도 result table에 포함시키는 join을 말합니다.

SELECT * FROM employee E LEFT OUTER JOIN department D ON E.dept_id = D.id;
여기서 LEFT는 왼쪽 테이블, 즉 employee 테이블을 의미하며 이 테이블에서 join condition을 만족하지 않는 튜플을 결과테이블에 포함해서 반환하라는 의미 입니다.

이렇듯 department 테이블에서 HR은 포함되지 않고 employee 테이블에서 생략됐었던 SIMON이 포함된 것을 확인할 수 있습니다.
SELECT * FROM employee E RIGHT OUTER JOIN department D ON E.dept_id = D.id;

이때는, 오른쪽 테이블 즉 department테이블에 누락됐었던 HR 데이터를 결과 테이블에 포함시킨 것을 확인할 수 있습니다. 그리고 마지막으로 FULL OUTER JOIN에 대해서 살펴보겠습니다. ❗️FULL OUTER JOIN은 postgreSQL에서 실행시켰는데 이유는 mySQL에서는 FULL OUTER JOIN을 지원하지 않기 때문입니다.
SELECT * FROM employee AS E FULL OUTER JOIN department D ON E.dept_id = D.id;

이렇듯 FULL OUTER JOIN은 예상했듯이 두 개의 테이블에서 매칭되지 않았던 튜플들까지도 결과 테이블에 포함시킨것을 확인 할 수 있습니다.
equi join
이퀴 조인은 join condition에서 =(equality comparator)를 사용하는 join을 의미합니다. 즉 위에서 설명했던 모든 예문들은 이 조인에 해당한다고 생각하시면 됩니다.

사실 이 equi join에 대해서는 두 가지 시각이 있는데 그것은 다음과 같습니다. 그리고 이 블로그에서 배우는 시각은 첫번째 임을 알려드립니다.
- inner join, outer join 상관없이 = 를 사용한 join이라면 equi join으로 보는 경우
- inner join으로 한정해서 = 를 사용한 경우에 equi join으로 보는 경우
using
using은 ⭐️두 테이블이 equi join할 때, join하는 attribute의 이름이 같다면, USING으로 간단하게 작성할 수 있다. 그리고 같은 이름의 attribute는 result table에서 한번만 표시된다. 아래 예시를 살펴보면 department의 id 속성의 이름을 dept_id로 변경해보자. 그러면 이 속성이름은 join테이블인 employee의 dept_id와 이름이 같게 된다.

그리고 결과를 살펴보면 아래와 같이 똑같은 이름의 데이터값들을 확인할 수 있는데, 💡그러면 이렇게 두번 나오도록 하지말고 한번만 표시되도록 할 수 없을까? 라는 의문이 생기는데❗️이때 사용하는 것이 바로 USING입니다.

USING을 사용하면 결과 테이블에 dept_id 속성이 한번만 표시가 됩니다.
SELECT * FROM employee E INNER JOIN department D USING (dept_id);


natural join
네추럴 조인은 ⭐️두 테이블에서 같은 이름을 가지는 모든 attribute pair에 대해서 equi join을 수행하는 것을 의미하고 join condition을 따로 명시하지는 않습니다. 아래 사진처럼 다양한 종류가 있지만 대표적으로 NATURAL INNER JOIN을 통해 배워보겠습니다.

SELECT FROM employee E NATURAL INNER JOIN department D;
아래 사진 처럼 원래는 department의 name 속성이 name이었는데, dept_name으로 변경하였고, 이 상태에서 위 쿼리문을 실행하면 employee의 dept_id와 department의 dept_id가 equi join이 됩니다.


❗️그러면 department의 name을 왜 dept_name으로 변경한걸까요? 먼저 만약 이름을 바꿔주지 않고 쿼리문을 실행하면 아무런 결과값도 반환되지 않습니다. natural join은 이름이 같은 모든 속성 pair에 대해서 equi join을 하는 것인데, employee의 name과 department의 name 데이터가 같지 않기 때문입니다.

SELECT * FROM employee E NATURAL INNER JOIN department D;
위 쿼리는 아래 쿼리와 같습니다.
SELECT * FROM employee E INNER JOIN department D USING (dept_id, name);
또 ON 을 통해 작성하면 다음과 같습니다.
SELECT * FROM employee E INNER JOIN department D ON E.dept_id = D.dept_id
AND E.name = D.name;
❗️즉 임직원이 속한 부서 아이디와 부서 테이블의 아이디가 같고 임직원의 이름과 부서의 이름이 같은 데이터를 조회하라는 뜻인데, 임직원 이름과 부서 이름은 같을 수 없기 때문에 제대로된 결과를 반환할 수 없는 것입니다.

cross join
크로스 조인은 두 테이블의 튜플 pair로 만들 수 있는 모든 조합(Cartesian Product)을 결과 테이블로 반환하는 것입니다. 그래서 join condition이 따로 없고 표현할 수 있는 방식은 두 가지가 있습니다.
- implicit cross join: FROM table1, table2
- explicit cross join: FROM table1 CROSS JOIN table2


결과 값으로 모든 조합을 결과 테이블에 포함시켜서 반환됩니다. 아래 사진은 implicit cross join 방식이고 결과값은 같습니다.
SELECT * FROM employee, department;

❗️참고사항으로 mySQL에서 CROSS JOIN은 cross join = inner join = join 을 뜻합니다. 그리고 CROSS JOIN에서 ON (or USING)을 같이 쓰면 inner join으로 동작하고 INNER JOIN (or JOIN)이 ON(or USING)없이 사용되면 cross join으로 동작합니다.
self join
셀프 조인은 테이블이 자기 자신에게 join하는 경우를 말합니다. 즉, 자기 자신에게도 조인을 할 수 있습니다.
join example
- ID가 1003인 부서에 속하는 임직원 중 리더를 제외한 부서원의 ID, 이름, 연봉을 알고 싶다.
SELECT E.id, E.name, E.salary FROM employee E JOIN department D ON E.dept_id = D.id
WHERE E.dept_id = 1003 AND E.id != D.leader_id;
- ID가 2001인 프로젝트에 참여한 임직원들의 이름과 직군과 소속 부서 이름을 알고싶다.
SELECT E.name AS empl_name, E.position AS empl_position, D.name AS dept_name
FROM works_on W JOIN employee E ON W.empl_id = E.id
LEFT JOIN department D ON E.dept_id = D.id
WHERE W.proj_id = 2001;
from 절을 보면, works_on table을 employee 테이블을 inner join 해준다. W.empl_id = E.id. 그리고 또 join을 해주어야 하는데, 소속 부서의 이름도 알아야하기 때문이다. ❗️이때, LEFT OUTER JOIN을 해주어야한다. E.dept_id = D.id. 그 이유는 혹시나 E.dept_id가 NULL인 경우에도 최종적인 결과에도 employee의 정보가 남아 있을 수 있기 때문이다.
지금까지 join과 관련된 개념과 기본 예제에 대해서 배워보았습니다. 항상 기본이 중요하듯이 반복적으로 공부하면서 익숙해지길...
'CS 지식 > 데이터베이스' 카테고리의 다른 글
SQL 데이터 조회: group by, aggregate function, order by (1) | 2023.09.19 |
---|---|
SQL로 데이터 조회하기, NULL (0) | 2023.09.16 |
⭐️SQL 데이터 조회: subquery (0) | 2023.09.14 |