#Join 여러 테이블을 연결 할 때 사용
테이블 끼리 연결하기 위해선 공통된 정보를 담은 필드가 필요.
해당 데이터베이스에서는 user_id, course_id 로 사용된다.. Key값의 개념.
exel의 vlookup과 비슷한 개념을 가진다.
Left join, Inner Join으로 구분된다.
Left = [합집합의 개념]
A에 B를 붙여라 B의 키값이 NULL 이면 차집합
Inner = [교집합의 개념]
사용법 left join [붙일 테이블명][별칭] on [기준이될 키값 필드] = [붙여질 키값 필드]
Ex. left join point_users pu on u.user_id = pu.user_id
~연습1. orders 테이블에 users 테이블 연결
SELECT * FROM orders o
inner join users u on o.user_id = u.user_id
~연습2. checkins 테이블에 users 테이블 연결
SELECT * FROM checkins c
inner join users u on c.user_id = u.user_id
~연습3. enrolleds 테이블에 courses 테이블 연결
SELECT * FROM enrolleds e
inner join courses c on e.course_id = c.course_id
쿼리 실행순서.
select * from [A 테이블] A
inner join [B 테이블] B
on A.[Key 필드] = B.[Key 필드]
from [A 테이블] A
A테이블의 전체 데이터를 가져온다.
inner join [B 테이블] B on A.[Key 필드] = B.[Key 필드]
B테이블을 A테이블에 연결시키는데 이때,
A테이블의 [Key 필드]와 동일한 B테이블의 [Key 필드]를 갖는 값만을 A테이블에 붙인다.
3.Select *
붙여진 모든 데이터를 출력시킨다.
~연습4. 오늘의 다짐 정보에 과목정보를 연걸해 과목별 오늘의 다짐 갯수를 세어보자
SELECT c2.title , count(*) FROM checkins c
inner join courses c2 on c.course_id = c2.course_id
group by c.course_id
~연습5. 유저의 포인트 정보가 담긴 테이블에 유저의 정보를 연결해서, 많은 포인트를 얻은 순서대로 유저의 데이터뽑기
SELECT pu.user_id, pu.point
, u.name, u.email from point_users pu
inner join users u on pu.user_id = u.user_id
order by pu.point
desc
~연습6. 주문 정보에 유저 정보를 연결해 네이버 이메일을 사용하는 유저 중, 성씨별 주문건수를 세어보자.
SELECT u.name, o.email, 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
~퀴즈1. 결제 수단 별 유저포인트의 평균값 구하기.
SELECT o.payment_method, round(avg(pu.point
),0) from orders o
inner join point_users pu on o.user_id = pu.user_id
group by o.payment_method
~퀴즈2. 결제하고 시작하지 않은 유저들을 성씨별로 세어보기.
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
~퀴즈3. 과목 별로 시작하지 않은 유저들을 세어보기
SELECT c.title, c.course_id, count(*) as cnt_notstart from courses c
inner join enrolleds e on c.course_id = e.course_id
WHERE e.is_registered = 0
group by c.title
~퀴즈4. 웹개발, 앱개발 종합반의 week 별 체크인수를 세어보자.
SELECT c.title ,c2.week, COUNT(*) as cnt from courses c
inner join checkins c2 on c.course_id = c2.course_id
group by c2.week, c.title
order by c.title, cnt desc
~퀴즈5. 연습4번에서 8월1일 이후에 구매한 고객들만 추출하기.
SELECT c.title ,c2.week, COUNT(*) as cnt from courses c
inner join checkins c2 on c.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 c2.week, c.title
order by c.title, cnt desc
#Left Join 은 좌측 테이블에 붙이는것으로 순서가 중요하다.
한쪽에는 있으나 다른 한쪽에는 없는 것을 통계내고 싶을 경우
users에 point_users의 user_id로 묶어준후에
pu의 user id가 null 값인 사람만을 비교하고 이름으로 정렬하면
포인트가 없는 사람의 수를 샐수있다.
~퀴즈6. 7월10일 ~ 7월 19일에 가입한 고객중 포인트를 가진 고객의 수, 전체 고객수, 그 비율구하기
SELECT count(u.user_id)as tot, count(pu.point
)as pnt, round(count(pu.point
)/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'
포인트를 가진 고객의 수를 구하기 위해서는 point나 point_user_id 같이 시작을 안햇다면 Null 값을 지니는 항목을 Count 하고
전체 고객수를 구하기 위해서는 각 고객이 모두 지니는 user_id를 구하면 된다.
그후 전체 고객의 수에서 point나 point_user_id를 가진 고객의 수를 나눠주면 비율이 구해진다.
#UNION
2종류 이상의 쿼리문을 이어서 출력할때 사용한다
쿼리문을 소괄호 ( ) 로 묶어주고 후술되는 쿼리문의 소괄호 ( ) 앞에 Union all을 붙여준다.
(
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
)
~숙제1. enrolled_id 별 수강완료 (done==1)한 강의 갯수를 세어보고 완료한 강의수가 많은 순서로 정렬하기
user_id도 같이 출력되어야 한다.
SELECT e.enrolled_id, e.user_id, count(ed.done)as max_count from enrolleds e
inner join enrolleds_detail ed on e.enrolled_id = ed.enrolled_id
where ed.done = 1
group by e.enrolled_id
order by max_count desc