부트캠프/SQL 도전기

4주차 엑셀 보다 쉬운 SQL 마무리

BTSBRINGMEHERE 2022. 2. 3. 16:30

# SQL 4주차 마무리

SUBQUERY란???

서브쿼리란 간단하게 말해서 쿼리안의 쿼리란 뜻 입니다. 하위 쿼리 값의 결과를 상위 쿼리에서 사용하면 훨씬 간편한 SQL 쿼리를 작성할 수 있습니다. 실제 실무에서는 생각보다 방대하고 복잡한 데이터가 있습니다. 이러한 데이터를 원하는 유의미한 정보로 만들기 위해서 서브쿼리를 사용하여 원하는 데이터만 뽑아 낼 수 있는 유용한 기능입니다.

 

서브쿼리는 where, select, from 절 등 에서 사용됩니다.

# where 절의 서브쿼리
select u.user_id, u.name, u.email from users u
where u.user_id in (
	select user_id from orders
	where payment_method = 'kakaopay'
)

# select 절의 서브쿼리
select c.checkin_id, c.user_id, c.likes, 
	(select avg(likes) from checkins c2
	where c2.user_id = c.user_id) as avg_like_user
from checkins c;

# from 절의 서브쿼리
select pu.user_id, a.avg_like, pu.point from point_users pu
inner join (
	select user_id, round(avg(likes),1) as avg_like from checkins
	group by user_id
) a on pu.user_id = a.user_id

처음 사용했을 때는 조금 복잡했지만 간단하게 2개의 쿼리를 만들고 원하는 문장속에 집어넣는다는 개념으로 생각했습니다.

 

WITH를 사용한 서브쿼리

서브쿼리를 2가지 이상 사용하면 본문을 읽기가 조금 힘들어 집니다. with를 사용해서 테이블을 만들어준 다음에 서브쿼리를 사용합니다. 그러면 훨씬 문장 읽기가 쉬워지고 깔끔해집니다.

 

with table1 as (
	select course_id, count(distinct(user_id)) as cnt_checkins from checkins
	group by course_id
), table2 as (
	select course_id, count(*) as cnt_total from orders
	group by course_id
)

select c.title,
       a.cnt_checkins,
       b.cnt_total,
       (a.cnt_checkins/b.cnt_total) as ratio
from table1 a inner join table2 b on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id

각각의 테이블을 형성해서 서브쿼리 역할을 해줍니다.

 

퀴즈

# 퀴즈 1
SELECT pu.point_user_id,
       pu.point,
       (case when pu.point > (select avg(point) from point_users) then '잘 하고 있어'
       else  '조금 더 화이팅' end ) as msg
from point_users pu

# 퀴즈 2
SELECT SUBSTRING_INDEX(email,'@',-1) as domain, count(*) as cnt_domain from users
group by domain

# 퀴즈 3 (서브 쿼리를 공부하니깐 복잡하게 가지말고 알고있는 문법들을 활용해서 쉽게만들어 보자는 취지였던 문제)
SELECT * from checkins
WHERE comment like ‘%화이팅%'
# 제가했던 방식
select a.enrolled_id,
       a.cnt,
       b.cnt_total,
       round((a.cnt/b.cnt_total),2) as ratio
from
(	SELECT enrolled_id, count(*) as cnt from enrolleds_detail
	where done = 1
	group by enrolled_id
) a
inner join
(
	SELECT enrolled_id, count(done) as cnt_total from enrolleds_detail
	group by enrolled_id
) b on a.enrolled_id = b.enrolled_id

# 답지에 나온 방식 with를 활용
with table1 as (
	select enrolled_id, count(*) as done_cnt from enrolleds_detail
	where done = 1
	group by enrolled_id
), table2 as (
	select enrolled_id, count(*) as total_cnt from enrolleds_detail
	group by enrolled_id
)

select a.enrolled_id,
       a.done_cnt,
       b.total_cnt,
       round(a.done_cnt/b.total_cnt,2) as ratio
  from table1 a
 inner join table2 b on a.enrolled_id = b.enrolled_id

확실히 with 문법을 활용하면 깔끔하게 나오는 것 같습니다. 

 

4주차 마무리.....

4주차 숙제는 따로 없습니다. 1주차 부터 4주차에 배운 문법들을 다시 복습하는 시간을 갖게 되었습니다.

엑셀보다 쉬운 SQL 회사 생활에 도움이 될까 해서 배웠는데 많은 도움이 된 것 같습니다. 사실 앱 개발도 수강하고 싶었지만 그래도 매우 만족하는 SQL 강의 였습니다. 웹개발과 SQL 수강을 마치고 다음에는 메이킹 챌린지를 수강하고 프론트 엔드 엔지니어로 취업을 희망하기에 리액트, 자바스크립트를 공부해서 취업을 하겠습니다.