예제는 User와 Team으로 하겠습니다.
User는 Team에 가입할 수도 있고 없을 수도 있습니다.
DB에는 Team에 가입한 User와 그렇지 않은 User 데이터가 존재합니다.
[문제]
어떠한 User를 조회하는 데 가입한 Team이 있다면 User.id로 JOIN하여 함께 조회
문제에 따라 데이터를 조회한다고 했을 때, 이렇게 두 가지 경우가 있다는 것을 생각해 볼 수 있습니다.
1. 특정 User가 가입한 Team이 있는 경우
2. 특정 User가 가입한 Team이 없는 경우
[풀이]
# 1
select * from user u
left join team t
on u.id = t.user_id
where u.id = '1';
# 2
select * from user u
join team t
on u.id = t.user_id
where u.id = '1';
# 3
select * from user u
join team t
on u.id = t.user_id
and u.id = '1';
# 4
select * from user u
left join team t
on u.id = t.user_id
and u.id = '1';
4가지 쿼리를 작성해보았고 2번에 대해서 얘기해보겠다.
#1은 User는 조회되고 Team 정보는 없을 것이다.
#2는 Team 데이터가 없기 때문에 Null
#3은 Team 데이터가 없기 때문에 Null
#4는 DB에 존재하는 모든 User 데이터가 조회되며, Team이 존재하는 User의 경우에는 Team 데이터가 함께 조회될 것이다.
#4를 통해 LEFT JOIN 조건절에서 Key에 대한 추가 조건을 작성해도 큰 의미가 없다는 사실을 알 수 있다.
JOIN 조건절 안에서는 Key가 아닌 다른 필드에 대한 조건을 걸어야 한다.
[문제] 특정 Team이라는 조건 추가
User(id=1)은 가입한 Team이 없는 문제 2의 상황
# 1
select * from user u
left join team t
on u.id = t.user_id
where 1
and u.id = '1'
and t.name = 'A';
# 2
select * from user u
join team t
on u.id = t.user_id
where 1
and u.id = '1'
and t.name = 'A';
# 3
select * from user u
join team t
on u.id = t.user_id
and t.name = 'A'
where u.id = '1';
# 4
select * from user u
left join team t
on u.id = t.user_id
and t.name = 'A'
where u.id = '1';
#1은 Null
#2도 Null
#3도 Null
#4는 User는 조회되고 Team은 조회되지 않는다.
[마무리] 특정 User에 대한 조건을 제거
INNER JOIN은 특정 조건에 어긋나면, Null을 반환한다.
하지만 특정 데이터를 보내줄 때, ORM을 사용하면 기반 데이터를 중심으로 LEFT JOIN하여 데이터를 조합한다.
# 1
select * from user u
left join team t
on u.id = t.user_id
and t.name = 'A';
# 2
select * from user u
left join team t
on u.id = t.user_id
where t.name = 'A';
#1은 User는 조회되고 Team은 조회되지 않는다. 조회되지 않음은 Null을 말한다.
#2는 Null
user = userRepository().get()을 할 때, user는 무조건 조회될 것이라고 생각할 수 있다.
(map 처리를 해서 team 데이터를 가공하는 그림을 그리면서)
하지만 #2 쿼리를 작성하면 Null이 반환돼 예외가 발생할 수 있다.
조인해야 할 테이블과 조건이 많아질수록 놓칠 수 있는 부분이라고 생각한다. 이를 주의하자.
'SQL' 카테고리의 다른 글
FK (외래키)에 대해서 끄적끄적... (2) | 2024.04.27 |
---|