테이블은 목적에 맞게 나눠놓는게 가장 좋은 방법
나눠져있는 테이블들을 붙이는 게 Join
두 테이블을 붙일 때 A테이블, B테이블 모두 가지고 있는 정보(공통된 정보=key 값)를 기준으로 삼아서 붙여서 한 테이블처럼 본다.
엑셀의 vlookup과 비슷함
- Left Join
A테이블과 B테이블이 있을 때 A테이블을 기준으로 붙이는 것
users 테이블에 point_users 테이블을 붙여보자
select * from users u
left join point_users p
on u.user_id = p.user_id
출력화면
point_user_id의 null값은 매칭이 안된 경우
모든 user가 포인트를 가지고 있는 게 아니니까 매칭이 안될 수 있음
is NULL
유저 중에 포인트가 없는 사람(=즉, 시작하지 않은 사람들)의 통계
select name, count(*) from users u
left join point_users pu on u.user_id = pu.user_id
where pu.point_user_id is NULL
group by name
출력화면
is not NULL
유저 중에 포인트가 있는 사람(=즉, 시작한 사람들)의 통계
select name, count(*) from users u
left join point_users pu on u.user_id = pu.user_id
where pu.point_user_id is not NULL
group by name
left join 실습
7월10일 ~ 7월19일에 가입한 고객 중, 포인트를 가진 고객의 숫자, 그리고 전체 숫자와 비율보기
point_user_id의 개수를 세면 null이 아닌 데이터만 카운트된다.
select count(pu.point_user_id) as pnt_user_cnt,
count(u.user_id) as tot_user_cnt,
round(count(pu.point_user_id)/count(u.user_id),2) as ratio
from users u
left join point_users pu on u.user_id = pu.user_id
where u.created_at between '2020-07-10' and '2020-07-20'
출력화면
- Inner Join
left join코드에서 left를 inner로 바꿔주면 된다.
select * from users u
inner join point_users p
on u.user_id = p.user_id
on을 기준으로 교집합만 출력된다.
출력화면
inner join 실습
!두 테이블을 조회해보고 공통되는 걸 확인하고 기준으로 잡기
select * from orders o
inner join users u on o.user_id = u.user_id
select * from checkins c
inner join users u on c.user_id = u.user_id
select * from enrolleds e
inner join courses c on e.course_id = c.course_id
c의 course_id로 그룹화
select c.course_id, count(*) as cnt from checkins c
inner join courses c2 on c.course_id = c2.course_id
group by c.course_id
select pu.user_id, u.name, u.email, pu.point from point_users pu
inner join users u on pu.user_id = u.user_id
order by pu.point desc
select u.name, count(*) as cnt from orders o
inner join users u on o.user_id = u.user_id
where o.email like '%naver.com'
group by u.name
select c1.title, c2.week, count(*) from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
group by c1.title, c2.week
order by c1.title, c2.week
union
(
select '7월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
)
union all
(
select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c1.course_id = c2.course_id
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
)
7,8월이 붙어서 출력된다.
단, order by한 상태에서는 union이 안되고
union을 한 상태에서 order를 해야한다.