TIL 2021.07.22 | (SQL) JOIN
오늘은 오답노트 느낌이 나는 TIL 게시글입니다. 쿼리가 몇 줄만 길어져도 너무 헷갈립니다. 너무 에러가 많이 떴어서 이제 당황하지도 않습니다.😭 어제 TIL을 건너뛴 것을 반성합니다.(T_T)
SQL을 다루는 것이 아직 많이 서툽니다. 틀린 점이나 개선해야할 점을 남겨주시는 것은 언제나 환영입니다. 🙏
● 여름방학 SQL 공부하기
SQL 이론 학습을 위해 SQLD 공부 중 → 9월 中 SQLD 자격 취득이 목표
SQL 학습을 위해 온라인 강의 수강 중: 스파르타 코딩클럽
TIL 2021.07.22 start!
1. 여러 테이블을 연결해주는 Join
1) Join 란?
▶두 테이블의 공통된 정보 (key값)를 기준으로 테이블을 연결해서 한 테이블처럼 보는 것을 의미. → 집합관계
▶엑셀의 vlookup 역할을 함.
2) Join의 종류
▶left join (NULL 즉, 빈 필드도 모두 나옴)
: A와 B는 각각의 테이블을 의미. 둘 사이의 겹치는 부분은, 뭔가 테이블 A와 B의 key 값이 연결되는 부분.
select * from users u
left join point_users p on u.user_id = p.user_id
▶inner join (교집합으로 빈 필드는 나오지 않음)
: left join은 순서가 중요하지만 inner join은 교집합이기 때문에 순서가 중요하진 않음.
select * from users u
inner join point_users p on u.user_id = p.user_id
3) 쿼리 실행 순서
▶from → join → select
▶from → join → where → group by → select
select u.name, count(u.name) as count_name from orders o
inner join users u
on o.user_id = u.user_id
where u.email like '%naver.com'
group by u.name
2. 오늘의 연습💛
#퀴즈1. 결제 수단별 유저 포인트의 평균값 구해보기
#나의 첫 답안
select pu.point, avg(*) from point_users pu
inner join orders o on o.user_id = pu.user_id
where o.payment_method
group by pu.point
#정답
select o.payment_method, round(avg(pu.point),2) from point_users pu
inner join orders o on o.user_id = pu.user_id
group by o.payment_method
- ~별 : group by / 결제수단별: group by payment_method
- 결제수단을 선택하고 그 결제 수단의 포인트의 평균값이니,
select o.payment_method, avg(pu.point) from point_users pu
❗ 제발 머리로 글을 써보고 쿼리 작성하기 ❗
#퀴즈2. 결제하고 수업을 시작하지 않은 유저들을 성씨별로 세어보기
#안한 사람 0으로 표기, 한 사람 1로 표기 되어 있음
#나의 첫 답안
select u.name, count(is_registered) from enrolleds e
inner join users u on u.user_id = e.user_id
group by u.name
#정답
select u.name, count(*) as cnt from enrolleds e
inner join users u on u.user_id = e.user_id
where e.is_registered = 0
group by u.name
order by count(*) des
- 수강을 하지 않은 사람만 따로 모아서 세어야하니까,
where e.is_registered = 0
#퀴즈3. 과목별로 시작하지 않은 유저들을 세어보기
#나의 첫 답안
select c.title, count(*) as cnt from courses c
inner join enrolleds e on e.course_id = c.course_id
where e.is_registered = 0
group by c.title
#정답
select c.course_id, c.title, count(*) as cnt_nonstart from courses c
inner join enrolleds e on e.course_id = c.course_id
where e.is_registered = 0
group by c.course_id
#퀴즈4. 웹개발, 앱개발 종합반의 week별 체크인 수를 세어보기.
#나의 첫 답안
select c.course_id, c.title, count(ch.week) as cnt from courses c
inner join checkins ch on ch.course_id = c.course_id
group by ch.week
#정답
select c.title, ch.week, count(*) as cnt from courses c
inner join checkins ch on ch.course_id = c.course_id
group by c.title, ch.week
order by c.title, ch.week
웹개발, 앱개발 종합반의 week별 : group by A, B
#퀴즈5. 퀴즈 4번에서 8월 1일 이후에 구매한 고객들만 추출
#나의 첫 답안
select c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c2.course_id = c1. course_id
inner join orders o on o.user_id = c2.user_id
where o.created_at()
group by c1.title, c2.week
order by c1.title, c2.week
#정답
select c1.title, c2.week, count(*) as cnt from courses c1
inner join checkins c2 on c2.course_id = c1. course_id
inner join orders o on o.user_id = c2.user_id
where o.created_at >= '2020-08-01'
group by c1.title, c2.week
order by c1.title, c2.week
<= '날짜' / >='날짜' / bitween '날짜' and '날짜'
left join
#not NULL/ NULL
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
#퀴즈6. 7월10일~7월19일에 가입한 고객 중, 포인트를 가진 고객의 숫자, 그리고 전체 숫자, 그리고 비율
#나의 첫 답안
select pu.point_user_id, count(*) as cnt 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-19'
#정답
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'
숙제
#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 ed.enrolled_id = e.enrolled_id
group by ed.enrolled_id, ed.done
order by ed.done
#정답
select e.enrolled_id, e.user_id,
count(*) as max_count
from enrolleds e
inner join enrolleds_detail ed on ed.enrolled_id = e.enrolled_id
where ed.done = 1
group by e.enrolled_id, e.user_id
order by max_count desc
where ed.done = 1
3. 결과물을 합쳐주는 UNION
Select를 두 번 할 게 아니라, 한번에 모아서 보고싶은 경우.
단, 내부정렬 order by가 되지 않기 때문에 서브쿼리를 활용해야함.
(
select '7월' as month, c.title, c2.week, count(*) as cnt from checkins c2
inner join courses c on c2.course_id = c.course_id
inner join orders o on o.user_id = c2.user_id
where o.created_at < '2020-08-01'
group by c2.course_id, c2.week
order by c2.course_id, c2.week
)
union all
(
select '8월' as month, c.title, c2.week, count(*) as cnt from checkins c2
inner join courses c on c2.course_id = c.course_id
inner join orders o on o.user_id = c2.user_id
where o.created_at > '2020-08-01'
group by c2.course_id, c2.week
order by c2.course_id, c2.week
)
Author And Source
이 문제에 관하여(TIL 2021.07.22 | (SQL) JOIN), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dkswldp95/TIL-2021.07.22-SQL-JOIN저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)