(TIL) SQL문 INNER JOIN 과 LEFT OUTER JOIN

성종호·2022년 2월 3일

나는 처음 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일

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

답글 달기