join문 : 테이블과 테이블을 붙이는 것. 모든 쿼리에 조인이 들어간다고 봐도 무방함. 예를 들어, 오늘의 다짐 이벤트 당첨자를 선정해서 기프티콘을 준다. 10명 추첨해서 깊티 지급~ 그리고 join을 사용해서 key값으로 두 테이블을 연결하곤함. 엑셀의 vlookup과 동일함
종류 : left join(합집합(=), inner join
A테이블을 기준으로 B를 붙인다거나한다.
select * from users u
inner join point_users p on u.user_id = p.user_id
select c1.course_id, count(*) as cnt from checkins c1
inner join courses c2 on c1.course_id = c2.course_id #이줄에서 한번에 정의함.;
group by c1.course_id #c1과 c2중에 하나로 , course id별 개수를 정의하되 개수 변수 명칭은 cnt.
select c1.course_id, c2.title, count(*) as cnt from checkins c1
inner join courses c2 on c1.course_id = c2.course_id #이줄에서 한번에 정의함.;
group by c1.course_id #c1과 c2중에 하나로 , course id별 개수를 정의하되 개수 변수 명칭은 cnt. 그려면 변수 두개가 뜬다.
select * from point_users pu
inner join users u on pu.user_id = u.user_id
order by pu.point desc #point 열은 원래 users 테이블에서 비롯된 것이기 때문에... pu.를 써주어야 함.
orders 테이블에 users 연결하기. 네이버 메일 사용하는 유저의 성씨별 주문건수 세어보기. 뒤에 끼워젛는 것을 inner join 바로 다음에 쓰는 것이다.
select u.name, count(*) 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 from orders o
select from point_users pu
inner join orders o on pu.user_id = o.user_id
두번째 퀴즈 : 결제했는데 아직 시작 안한사람..
select u.name, count(*) as cnt_name from enrolleds e
inner join users u on e.user_id = u.user_id
where e.is_registered = 0 #아직 시작 안 한 사람
group by u.name
order by cnt_name desc
세번째 퀴즈 : week별 체크인 수를 세어보기
select c.title, ch.week,count(*) as cnt from courses c
inner join checkins ch on c.course_id = ch.course_id
group by c.title, ch.week
order by c.title
inner join 두 번 해서 테이블 세개묶기.
select * from courses c
inner join checkins ch on c.course_id = ch.course_id
inner join orders o on ch.user_id = o.user_id #어차피 직전에 checkin붙인 것이 효력이 생겨버려서, 한꺼번에 실행되는 것을 염두에 두면 이렇게 inner join 두 번 써도 무방하다.
where o.created_at >='2020-08-01'
left join은 언제 쓰이는 걸까? 이것은 합집합
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 not NULL
group by u.name
*7월 10-19일 가입한 고객 중 포인트를 가진 고객의 숫자, 전체 숫자, 비율을 보고싶다.
select * from users u
left join point_users pu on u.user_id = pu.user_id
select count(pu.point_user_id) as pnt_user_cnt,
count(u.user_id) as tnt_user_cnt,
round(count(pu.point_user_id)/count(u.user_id),2)
from users u #u를 기준으로 해야, NULL아닌것들이 세진다. 근데 이게 옆의 수랑 소급하는것이 아닌가봄 ㅇㅇ
left join point_users pu on u.user_id = pu.user_id
where u.created_at between '2020-07-10' and '2020-07-20' #알아서 NULL 제끼고 count되는 것이 디폴트다
(
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 #8월달의 쿼리 '8월 as month' 라고 맨 처음에 정의하는 것임. 맨 처음에 변수명과 함께 정의하기.
)
#union all에서는 order by가 먹히질 않는다는 특징이 있음.
* homework(어렵..) enrolled_id별 수강완료(done=1)한 강의 갯수를 세어보고, 완료한 강의 수가 많은 순서대로 정렬해보기. user_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