(TIL) SQL문 INNER JOIN 과 LEFT OUTER JOIN

성종호·2022년 2월 3일
2

나는 처음 Python Django ORM으로 처음 데이터 관련한 문법을 익혔고 SQL문을 공부하면서 Djnago ORM과 비교하면서 공부한걸 블로깅 하려 한다.

JOIN

먼저 테이블 구조를 보자면 교집합인 부분은 users.id 와 carts.user_id

users

carts

users 와 carts에 들어있는 데이터

INNER JOIN

JOIN은 집합과 관계가 있고 집합마다 JOIN방식이 달라진다.
집합에는 곱집합, 교집합, 합집합 등 여러가지가 있는데
INNER JOIN = 교집합, OUTER JOIN = 합집합만 다뤄보겠다.

교집합 = INNER JOIN의 형태로 데이터를 불러오게 되고 INNER JOIN으로 불러오는 조건은 2개의 테이블이 참조관계에 있고 Foreign KEY의 옵션이 NULL = False 일경우 이다.
(Django 의 경우 on_delete=models.CASCADE 도 포함)

SQL문 과 값

SELECT * FROM carts INNERT JOIN users ON (users.id=carts.user_id) 
SELECT * FROM carts,users WHERE (users.id=carts.user_id)
둘다 같은 방식이며 2번째 줄 방식이 더 구식이라 한다.

LEFT OUTER JOIN

합집합 = OUTER JOIN 의 형태로 데이터를 불러오게 되고
2개의 테이블이 참조관계에 있지만 Foreign KEY 의 옵션이
NULL = False 여야 함
LEFT OUTER JOIN의 경우 부모와 자식테이블을 JOIN 할때 부모를 참조하는 자식 값이 없을때도 모든 부모테이블의 값을 불러오게 하기위함이다.

SQL문 과 값

SELECT * FROM carts LEFT OUTER JOIN users ON (users.id=carts.user_id) 

이상한점

INNER JOIN과 OUTER JOIN으로 가져온 값을 보면 이상한 점이 하나 있다.

그건 id 컬럼값이 중복 된다는 건데 두테이블 다 id라는 컬럼이 있고 JOIN을 했을때 두테이블을 합치는 과정에서 생긴건데 그럴경우

SELECT users.id AS user_pk FROM carts INNERT JOIN users ON (users.id=carts.user_id) 
SELECT users.id AS user_pk FROM carts LEFT OUTER JOIN users ON (users.id=carts.user_id) 

이런식으로 users.id 의 별명을 바꿔주면 된다.


select_related의 경우 정참조의 상황에서 쓰이고 SQL내부에서 JOIN해서 가져오며 쿼리는 1번 날림

1 : 1 정참조 관계 INNER JOIN
1 : 1 정참조 관계 LEFT OUTER JOIN
M : 1 정참조 관계 INNER JOIN

NULL = TRUE 의경우 LEFT OUTER JOIN
NULL = FALSE or on_delete=models.CASCADE 의경우 INNER JOIN

Cart.object.all().select_related("user")


1 : M 역참조 관계 Python LEVEL 에서 INNER JOIN
M : M 역참조 관계 Python LEVEL 에서 INNER JOIN
M : 1 정참조 관계 Python LEVEL 에서 INNER JOIN

prefetch_related의 경우 1+N번의 쿼리를 날리고 가져온다음
Python LEVEL에서 JOIN을 하며 INNER JOIN으로 참조,역참조 값을 가져온다.

User.objects.all().prefetch_related("cart_set")

일반적인 참조, 역참조

참조

역참조

둘다 구식의 INNER JOIN 형태로 가져온다.


TIL 후기

Python Django 로 개발하면서 django-extensions로 쿼리문 날아가는걸 봤을때 join을 보고 궁금했고 공부하고 싶었는데 뭔가 간지러운 부분을 긁은것 같아 속시원했다.

profile
아자

2개의 댓글

comment-user-thumbnail
2022년 11월 1일

좋은 글 잘 읽고갑니다!
LEFT OUTER JOIN에 대한 설명에서 오탈자가 있는것 같아요~ Null = True 일때 outer join이요!

답글 달기
comment-user-thumbnail
2023년 1월 17일

항상 많은 도움이 됩니다. 감사합니다~!

답글 달기