엑셀보다 쉬운 SQL - 4주차

subquery, 유용한 문법들

  • Subquery(서브쿼리)의 사용 방법을 배워본다
  • 실전에서 유용한 SQL 문법을 더 배워본다
  • SQL을 사용하여 실전과 같은 데이터분석을 진행해본다
  1. subquery
    하나의 SQL 쿼리 안에 또다른 SQL 쿼리가 있는 것을 의미
    쿼리식을 만들어서 직접 필요한 위치에 삽입
    -> join을 쓰지 않고도 같은 기능할 수 있음

ex) kakaopay로 결제한 유저들의 정보 보기

  • 카카오로 결제한 유저의 정보 보기(join 기능 이용)
select u.user_id, u.name, u.email from users u
inner join orders o on u.user_id = o.user_id
where o.payment_method = 'kakaopay'
  • subquery 이용

a. 우선 kakaopay로 결제한 user_id를 모두 구해보기(k)

select user_id from orders
where payment_method = 'kakaopay'

b. 그 후에, user_id가 K 에 있는 유저들만 골라보기

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'
)

1) where에 들어가는 subquery

-> where은 조건문이죠? Subquery의 결과를 조건에 활용하는 방식으로 유용하게 사용합니다.
where 필드명 in (subquery) 이런 방식으로요!

select * from users u
where u.user_id in (select o.user_id from orders o 
					where o.payment_method = 'kakaopay');

2) select에 들어가는 subquery

-> Select는 결과를 출력해주는 부분이죠? 기존 테이블에 함께 보고싶은 통계 데이터를 손쉽게 붙이는 것에 사용합니다.

select 필드명, 필드명, (subquery) from .. 이렇게요!

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;

3) From에 들어가는 subquery(가장 많이 사용)

-> From은 언제 사용하면 좋을까요? 내가 만든 Select와 이미 있는 테이블을 Join하고 싶을 때 사용하면 딱이겠죠!

  1. with절 연습하기
    with로 미리 subquery 내용을 써두면,
    아래에서 subquery를 as로 불러와서 간편하게 사용할 수 있음

<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

<with를 쓰지 않은 원래 코드>

select c.title,
       a.cnt_checkins,
       b.cnt_total,
       (a.cnt_checkins/b.cnt_total) as ratio
from
(
	select course_id, count(distinct(user_id)) as cnt_checkins from checkins
	group by course_id
) a
inner join
(
	select course_id, count(*) as cnt_total from orders
	group by course_id 
) b on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id
  1. 실전에서 유용한 SQL 문법 (문자열, Case)

1) 문자열 쪼개기

substring_index(필드,'기준문자',1 or -1)

-> 이메일 주소에서 @앞의 아이디만 가져오거나, @뒤의 이메일 도메인을 가져오고 싶어요!

2) 문자열 일부만 출력

substring(필드명,시작위치,끝위치)

select order_no, created_at, substring(created_at,1,10) as date from orders

3) CASE: 경우에 따라 원하는 값을 새 필드에 출력해보기

-> 10000점보다 높은 포인트를 가지고 있으면 '잘 하고 있어요!', 평균보다 낮으면 '조금 더 달려주세요!' 라고 표시해 주려면 어떻게 해야할까요?

select pu.point_user_id, pu.point,
case 
when pu.point > 10000 then '잘 하고 있어요!'
else '조금 더 달려주세요!'
END as '구분'
from point_users pu;

*subquery를 이용해서 통계를 낼 수 있음
a. 몇 가지로 구분을 나누고

select pu.point_user_id, pu.point,
case 
when pu.point > 10000 then '1만 이상'
when pu.point > 5000 then '5천 이상'
else '5천 미만'
END as lv
from point_users pu

b. subquery를 이용해서 group by로 통계 작성

select level, count(*) as cnt from (
	select pu.point_user_id, pu.point,
	case 
	when pu.point > 10000 then '1만 이상'
	when pu.point > 5000 then '5천 이상'
	else '5천 미만'
	END as lv
	from point_users pu
) a
group by lv

c. with절 이용

with table1 as (
	select pu.point_user_id, pu.point,
	case 
	when pu.point > 10000 then '1만 이상'
	when pu.point > 5000 then '5천 이상'
	else '5천 미만'
	END as lv
	from point_users pu
)

select level, count(*) as cnt from table1
group by lv
  1. 마치며

실제 업무에서 유용한 내용을 학습하는데 좋은 강의라고 생각한다.
자료를 다루는데 직접 DB에 접근해서 원하는 자료를 정리하고,
의미있는 데이터를 추출할 수 있는 문법을 배우는데 좋은 강의다.
지금 회사에서는 직접 접근할 수 있는 DB가 없기 때문에 공개된 DB를 통해 연습을 하거나, sql 문제 사이트에서 문제를 풀어봐야겠다.

4주차 숙제는 문법 정리이기 때문에 하나의 글을 더 써서 문법을 정리해야겠다.

좋은 웹페이지 즐겨찾기