[SQL] JOIN 하기

채록·2021년 3월 23일
0

Database

목록 보기
8/11
post-thumbnail

살아남기위해.. 익히고 적용한다..



0. JOIN

products라는 table이 있다고 가정한다. 그 products의 field중에는 seller의 id를 FK로 받는 field가 있을 것이다. (해당 상품을 게시한 판매자)

그렇다면 products로 접근해 products를 게시한 seller의 이름을 갖고오려면 어떻게 해야 할까?

먼저 이전에 Django를 사용했을때를 생각하면 아주 단순하다.

product = Products.objects.get(id=1)
products.seller.name
>>> "젤로"

하지만 위의 결과가 나오는 과정에서 db에 접근하는 방식을 알아보면 쉽게 JOIN이라는 단어를 찾아 볼 수 있다. 두개 이상의 table이 "연관"되어 데이터를 보내줄때 JOIN이 실행된다.


------------------------------


I. Cross Join (교차결합)

2개 이상의 table을 하나의 table처럼 나타낼때 사용된다. 특별한 구문은 없고 table은 ,(콤마) 로 구분한다. 두 테이블의 곱셈의 경우의수들에 대한 값이 instance로 표기된다

1. 기존의 두개 table

2. Cross Join 적용 후 #1 (SELECT * FROM users, dogs)

3. Cross Join 적용 후 #2 (SELECT * FROM dogs, users)

교차집합 결과 table을 보면 dogs의 id 순서대로 교차집합에 대한 결과들이 나열되어 있다 그리고 users 의 id가 dogs에 FK로 물려있어 구문 순서를 SELECT * FROM dogs, users로 해주었더니 dogs의 id가 가장 좌측에 존재해 보기 좋은 형태가 되었다.

Union vs Cross Join ?
Union은 세로 방향으로 Cross Join은 가로 방향으로 더해진다


------------------------------


II. JOIN의 종류 / 내부결합


1. FROM ~ INNER JOIN

예제로 살펴보기

Cross Join을 통해 두 테이블의 가로 합의 모든 경우의 수에 대한 Instance들이 출력되었다. 이중에서 우리가 찾고자 하는 값이 dogs의 users_id와 users의 id가 같을 조건만 확인하고자 한다.

다음과 같이 WHERE구문을 추가해 준다.

SELECT * FROM dogs, users WHERE dogs.user_id=users.id;

그결과 다음과 같이 나타난다

정확히 dogs에 따라 주인인 유저의 정보와 일치한 데이터들만 출력됨을 확인할 수 있다! 이처럼 교차결합으로 계산된 곱집합에서 원하는 조건을 검색하는 것을 내부결합이라고 한다.

+) WHERE 조건 추가하기

위의 출력된 결과에서 흡사 필터링처럼 원하는 조건이 있는 값만을 뽑아내고자 한다. 다음과 같이 입력한다.

SELECT * FROM dogs, users WHERE dogs.user_id=users.id AND users.age=20;

그 결과 다음과 같이 나타난다.

원하는 조건대로 user의 나이가 20세인 사람에 해당하는 결과만 나옴을 볼 수 있다!




2. 원하는 행 값만 뽑아내기

원하는 값이 강아지 이름과 user의 이름이라고 하자. SELECT 구문을 통해 확인하고자 하는 행을 지정해 준다.

SELECT dogs.name, users.name FROM dogs, users WHERE dogs.user_id=users.id AND users.age=20;

그 결과 다음과 같다.

짜잔!!!!



1) INNER JOIN 적용하기

이처럼 내부결합을 사용할때 위의 코드 대신 INNER JOIN이라는 구문을 사용하기도 한다! 적용방식은 다음과 같다.

SELECT dogs.name, users.name FROM dogs INNER JOIN users ON dogs.user_id=users.id WHERE users.age=20; 

SELECT 선택 행1(dogs.name), 선택 행2(users.name) FROM 테이블명1(dogs) INNER JOIN 테이블명2(users) ON 결합조건 WHERE 검색조건

FROM과 INNER JOIN의 순서 ?
위의 코드에서 dogsusers의 순서를 바꿔서 입력해도 같은 모양의 table이 출력된다.


2) AS 구문으로 별명 지정해서 사용하기

  1. FROM ~ INNER JOIN 에서 AS 구문으로 별명 지어 다른 구문에 적용시키기
  2. AS 생략하여 사용하기
  3. user의 id 출력하기
  4. user의 id field 이름을 UI로 지정하기



3. Self Join(자기 결합) 사용하기

이 기능을 위해선 별명 지정이 필수이다. 실제 코딩을할 때 이런 결합을 할 일은 없겠지만 일단 별명 지정을 통해 가능하다는 것!!


------------------------------


III. JOIN의 종류 / 외부결합

table B를 FK로 참조하는 tableA이 있는데 table B에 새로 추가된 new instance(이하 추가내용)을 참조하는 table A의 instance가 없다고 가정하자.

이와 같은 상황에서는 내부결합을 사용해도 추가내용에 대한 값은 나오지 않는다. table A에 출력될만한 추가내용이 없기 때문 이럴때 사용할 수 있는것이 외부결합 이다. 어떤 table을 기준으로 설정해줄지 결정할 수 있다.

mysql> SELECT * FROM dogs, users WHERE dogs.user_id=users.id;
+----+----------+-------------+-----+---------+----+-----------+-----+------------------+
| id | name     | breed       | age | user_id | id | name      | age | email            |
+----+----------+-------------+-----+---------+----+-----------+-----+------------------+
|  3 | 구름이    | 비숑          |   1 |       1 |  1 |**      |  27 | hello@gmail.com  |
|  2 | 하양이    | 말티즈         |   1 |       2 |  2 | 아무개     |  25 | some@gmail.com   |
|  1 | 까망이    | 푸들          |   2 |       4 |  4 | 보라돌이    |  20 | purple@gamil.com |
|  4 | 꼬맹이    | 치와와         |   1 |       4 |  4 | 보라돌이    |  20 | purple@gamil.com |
|  5 | 뽀송이    | 포메라니안      |   1 |       6 |  6 | 나나       |  18 | yellow@gmail.com |
+----+-----------+------------+-----+---------+----+------------+-----+-----------------+

위의 테이블을 보면 users에는 id=3인 "나그네"가 있는데 내부결합시엔 없다. dogs에서 "나그네"를 참조하는 값이 없기 때문이다.


1. LEFT JOIN

"users"을 기준으로 LEFT JOIN을 해보자.

FROM users LEFT JOIN dogs

users에는 있지만 dogs에서 참조하는 값이 없는 것들은 NULL로 표기된다.




2. RIGHT JOIN

위의 코드에서 users를 오른쪽에 기입하거나 / dogs table을 기준으로 삼고싶다면 RIGHT JOIN을 사용한다.


------------------------------


끝!

profile
🍎 🍊 🍋 🍏 🍇

0개의 댓글