[강의] 스파르타 코딩클럽 SQL 3주차

lzlkolo·2022년 12월 30일
0

테이블은 목적에 맞게 나눠놓는게 가장 좋은 방법
나눠져있는 테이블들을 붙이는 게 Join

두 테이블을 붙일 때 A테이블, B테이블 모두 가지고 있는 정보(공통된 정보=key 값)를 기준으로 삼아서 붙여서 한 테이블처럼 본다.
엑셀의 vlookup과 비슷함

  1. Left Join

A테이블과 B테이블이 있을 때 A테이블을 기준으로 붙이는 것

users 테이블에 point_users 테이블을 붙여보자

select * from users u
left join point_users p
on u.user_id = p.user_id 
  1. users(u) 테이블에 point_users(p)를 left join
  2. 그 기준(on)은 users테이블의 user_id, point_users테이블의 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'

출력화면

  1. 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 실습

!두 테이블을 조회해보고 공통되는 걸 확인하고 기준으로 잡기

  1. orders 테이블에 users 테이블 연결해보기(inner join)
select * from orders o 
inner join users u on o.user_id = u.user_id 
  1. checkins 테이블에 users 테이블 연결해보기(inner join)
select * from checkins c 
inner join users u on c.user_id = u.user_id 
  1. enrolleds 테이블에 courses 테이블 연결해보기(inner join)
select * from enrolleds e 
inner join courses c on e.course_id = c.course_id 
  1. checkins 테이블에 courses 테이블 연결해서 과목별 오늘의 다짐 갯수 세어보기

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
  1. point_users 테이블에 users 테이블 연결해서 순서대로 정렬해보기
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

  1. orders 테이블에 users 테이블 연결해서 네이버 이메일을 사용하는 유저의 성씨별 주문건수 세어보기
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 

  1. 웹개발, 앱개발 종합반의 week별 체크인 수(courses, checkins)
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를 해야한다.

0개의 댓글

관련 채용 정보