SQL을 공부하는데 JOIN이 헷갈려서 확실하게 정리를 하고 가야겠다!
우선, 많은 곳에서 JOIN을 집합을 이용해 설명을 하는데 직관적으로 잘 이해가 되긴 하지만 막상 적용하려면 헷갈리기 시작한다.
그래서 적용을 쉽게 하려면 table로 생각하면 편하다.
위와 같이 두 개의 테이블이 하나의 테이블로 합쳐지는 과정을 생각해보면 된다.
저 그림은 inner join을 나타내는 것이지만, 어떤 join이든 간에 중요한건 저 두 가지 테이블을 합친다는 개념을 갖고 있는것이다!
그럼 이제 JOIN에는 어떤 것이 있는지 살펴보겠다.
크게 두 가지의 join으로 나뉘고, outer join은 또 3가지로 나뉘게 된다.
저렇게 보면 헷갈리지만 사실 별거 없다.
실습해볼 스키마는 다음과 같다.
위 스키마에서 user테이블과 content테이블을 합치는 경우를 생각해보자.
합치는 조건은 두 테이블 모두 공통으로 가지고 있는 값(user의 id)을 기준으로 둘 다 값이 있는 레코드만 가진 새로운 테이블을 만든다.
SELECT * FROM user
JOIN content ON user.id=content.userId
여기서 user는 left, content는 right 테이블의 위치를 가지게 된다.
inner join은 두 테이블이 공통으로 가지고 있는 값만을 가지는 새로운 테이블을 만들다.
위와 유사하지만, 왼쪽에 위치한 테이블은 모든 값을 다 보여줄 것이다. 즉, 무슨 일이 있어도 왼쪽 테이블의 레코드들은 다 보여질 것이며, 오른쪽에 있는 합쳐지는 테이블에 빈 칸은 NULL
로 표현될 것이다.
SELECT * FROM user
LEFT JOIN content ON user.id=content.userId
이번엔 오른쪽 테이블은 그 값을 그대로 유지하고, 왼쪽 테이블에 없는 값은 NULL
로 표현되어 새로운 테이블을 만들 것이다.
SELECT * FROM user
RIGHT JOIN content ON user.id=content.userId
왼쪽, 오른쪽 모든 값을 유지할 것이다. 빈 레코드는 그냥 NULL
로 표시해주면 된다.
SELECT * FROM user
FULL JOIN content ON user.id=content.userId
SELECT user.name AS name, COUNT(content.id) AS ContentCount FROM user
LEFT JOIN content ON user.id=content.userId
GROUP BY name
user 테이블은 유지하고, content 테이블을 합쳐주는 명령어이다. 즉 쉽게 말해서 user 테이블의 행이 12줄이고, content 테이블의 행이 10줄이면 부족한 content 테이블의 행 부분은 다 NULL
로 처리를 해줄 것이란 뜻이다.
SELECT category.name FROM category
JOIN content_category ON category.id=content_category.categoryId
JOIN content ON content_category.contentId=content.id
JOIN user ON content.userId=user.id
WHERE user.name='JiSungPark';
여러 개(두 개 이상)의 테이블을 JOIN 해줄 수도 있다.
이때, 주의해야할 것은 조인을 하는 순서이다. 일대다의 관계에서 '일'인쪽으로부터 조인을 시작하면 쉽게 조인을 할 수 있다.
뭔말인지 모르겠으면, 위의 스키마를 다시 보고 오자.
하나의 카테고리는 여러개의 컨텐트를 가질 수 있다. (JOIN이랑 LEFT JOIN이랑 같은 효과(?))
가장 좋은 방법은 테이블 두개를 합치는게 JOIN 이라고 생각하는 것이다!
이때 두 테이블은 방향성을 가진다. 하나는 왼쪽, 하나는 오른쪽에 위치한다.