니모의 기록/하찮은 개발일지

SQL 개발일지 (3) - Join에 대해 배워볼 차례!

전세계 맛집 유랑단 단장 2022. 2. 24. 21:51

Join은 테이블과 테이블을 붙이는 것, 실무에서 거의 모든 쿼리에 들어가는 거라고 보면 된다.


상황: 
'오늘의 다짐' 이벤트 당첨자를 선정해서 기프티콘을 지급해야한다. 이를 위해 10명을 추첨하고자 한다면?

checkins 테이블에는 이름은 없고 user_id만 있음.
users 테이블에는 '오늘의 다짐' 정보는 없고, 유저 정보만 있음.

그래서 이 checkins 테이블과 users 테이블을 Join 해야하는 것!

테이블들을 서로 이어줄 때 중요한 건 기준!
- 중복되는 필드를 매칭시키기


Join이란 두 테이블의 공통된 정보(key값)을 기준으로 테이블을 연결해서 한 테이블처럼 보는 것을 의미.

* 엑셀의 vlookup과 동일.

 

Join의 종류: Left Join, Inner Join, (Outer Join)

■ Left Join이란?

두 개의 테이블 데이터를 모두 보여주는데, 이 때 왼쪽에 있는 테이블을 기준으로.

select * from users u
left join point_users pu 
on u.user_id = pu.user_id 

 

■ Inner Join?
포인트가 있는 것만 보여짐 (교집합)

 

[실습]
1. orders 테이블에 users 테이블 연결해보기
select * from orders o
inner join users u o.user_id = u.user_id
2. checkins 테이블에 users 테이블 연결해보기
SELECT * from checkins c 
inner join users u on u.user_id = c.user_id 
3.enrolleds 테이블에 courses 테이블 연결해보기
select * from enrolleds e
inner join courses c on e.course_id

 

 

select * from enrolleds e
inner join courses c
on e.course_id = c.course_id

쿼리가 실행되는 순서 
from -> join -> select

 

 

실행순서 확인!



이제는 실전! 본격 쿼리 작성해보기

Quiz (Join 연습) :
1. 결제수단별 유저의 포인트 평균값 구하기
(어떤 결제수단이 가장 열심히 듣고있나~)
Join할 테이블: point_users에 orders 붙이기
* 꿀팁: round(숫자, 자릿수)를 이용해 반올림!

2. 결제하고 시작하지 않은 유저들을 성씨별로 세어보기
(어느 성이 가장 시작을 안 했는가~)
Join할 테이블: enrolleds에 users 붙이기
* 꿀팁: is_registered = 0 인 사람들을 세어보아요!
* 꿀팁: order by 를 이용해서 내림차순으로 정렬하면 보기가 좋습니다!

3. 과목별로 시작하지 않은 유저들 세어보기
Join할 테이블: courses에 enrolleds 붙이기
* 꿀팁: is_registered = 0 인 사람들 세어보아요!

as로 이름을 붙여줄 때 좀 더 직관적으로 확인할 수 있도록 설정하는 것도 하나의 방법!

 

4. 웹개발, 앱개발 종합반의 week별 체크인 수 세어보기 (보기 좋게 정리하기!)
Join할 테이블: courses에 checkins 붙이기
* 꿀팁: group by, order by에 콤마로 이어서 두 개 필드를 걸어보세요!

5. 연습 4번에서 8월 1일 이후에 구매한 고객들만 발라내어 보세요!
Join할 테이블: courses에 checkins를 붙이고, checkins에 orders 한 번 더 붙이기!
* 꿀팁: orders 테이블에 inner join 한 번 더 걸고 where절로 마무리.

그 누구도 한 번에 쭉 위에서부터 써서 완벽하게 결과값을 출력해낼 수 없으니, 틀리면 수정하고 또 수정해서 데이터가 나오게 만드는 게 중요..!

 


 

Left Join 연습!
* 어디에 뭐를 붙일 건지, 순서가 중요

한쪽엔 있는데 한쪽에 없는 걸 가지고 통계를 내고 싶을 때?

select * from poin_users pu
select * from users 

users의 모든 유저가 포인트를 갖고 있진 않기 때문에 users를 기준으로 point_users를 붙여보기.

select * from users u
left join point_users pu on u.user_id = pu.user_id 

이렇게 입력했을 때 NULL값이 나오는 유저들이 있다. (포인트가 없는 유저)

where pu.point_user id is NULL

이렇게 입력하면 NULL인 유저만 보여주게 됨

group by u.name
을 입력해주고 나서 select문을 수정해 준다.

select u.name, count(*) as cnt from users u
left join point_users pu on u.user_id = pu.user_id 
where pu.point_user id is NULL
group by u.name

where절에서 is NULL 또는 is not NULL을 입력함으로써 반대의 유저를 추출해볼 수도 있다!

 

 


 

숙제: enrolled_id별 수강완료(done=1)한 강의 갯수를 세어보고, 완료한 강의 수가 많은 순서대로 정렬해보기. user_id도 같이 출력되어야 한다.

조인해야 하는 테이블: enrolleds, enrolleds_detail
조인해야 하는 필드: enrolled_id

 

select e.enrolled_id,e.user_id, count(*) as cnt from enrolleds e
inner join enrolleds_detail ed on e.enrolled_id = ed.enrolled_id 
where ed.done = 1
group by e.enrolled_id,e.user_id
order by cnt desc

 

확실히 Join부터는 어려운 것 같다. 수강 완료 해놓고 복습할 겸 처음부터 다시 한 번 들어야지..! 

728x90
반응형