스파르타코딩/SQL

[스파르타코딩클럽] 엑셀보다 쉬운 SQL - 4주차 개발일지

햇살아래 2021. 6. 26. 23:16

4주차 수업목표

  • Subquery(서브쿼리)의 사용 방법을 배워본다
  • 실전에서 유용한 SQL 문법을 더 배워본다.
  • SQL을 사용하여 실전과 같은 데이터분석을 진행해본다.

 

 

01. Subquery란?

 쿼리 안의 쿼리라는 의미이다. 하위 쿼리의 결과를 상위 쿼리에서 사용하면, sql 쿼리가 훨씬 간단해진다.

즉, subquery를 사용하지 않아도 원하는 데이터를 얻어낼 수 있지만, 더 편하고 간단하게 원하는 데이터를 얻기 위해 사용되는 기능이다.

 

02. 원하는 데이터를 더 쉽게: subquery

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

 

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'

 

1. kakaopay로 결제한 user_id를 모두 구하기 -> k라고 지칭

select user_id from orders

where payment_method = 'kakaopay'

 

2. 그 후에, 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'

)

 

03. subquery 본격 사용해보기

-where절에 들어가는 subquery

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

 

실행 순서>

(1) from 실행 : users 데이터를 가져와줌

(2) Subquery 실행 : 해당되는 user_id의 명단을 뽑아준다.

(3) where .. in 절에서 subquery의 결과에 해당되는 'user_id의 명단' 조건으로 필터링 해줌

(4) 조건에 맞는 결과 출력

 

-select절에 들어가는 subquery

: 기존 테이블에 함께 보고싶은 통계 데이터를 붙일 때 사용

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

 

실행 순서>

(1) 밖의 select * from 문에서 데이터를 한줄한줄 출력하는 과정에서

(2) select 안의 subquery가 매 데이터 한줄마다 실행되는데

(3) 그 데이터 한 줄의 user_id를 갖는 데이터의 평균 좋아요 값을 subquery에서 계산해서

(4) 함께 출력

 

-from절에 들어가는 subquery(가장 많이 사용)

: 내가 만든 select와 이미 있는 테이블을 Join하고 싶을 때 사용

 

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

 

실행 순서>

(1) 먼저 서브쿼리의 select가 실행되고,

(2) 이것을 테이블처럼 여기고 밖의 select가 실행

 

04. with절 사용

 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