SQL | 서브쿼리(Subquery) 사용법 정리 | 서브쿼리 예제

    728x90

     

    0. 서브쿼리(Subquery) 어렵지 않아요!    (?ㅎ)

     

    내가 SQL을 처음 접하고, 

    나름 재미있게(?) 공부하다가 맞닥뜨린 첫 고비가 바로 서브쿼리였다. 

    SELECT절 / WHERE절 / FROM절다양한 위치에서 서브쿼리를 사용할 수 있다고 배웠는데

    도대체 언제 SELECT절에 서브쿼리를 쓰는지, 언제 FROM절에 서브쿼리를 쓰는지 감이 안와서 힘이 들었던 기억이 있다.

    이건 당시 내가 정리했던 SQL 서브쿼리 정리노트다. 

    (혹시 이 게시물보다 조금 더 자세한 설명이 필요하다면, 아래 게시글 참고 요망)

    [참고 게시글]

    [IT 교육/SQL] - SQL 4주차 강의 노트정리[국비지원_스파르타 코딩클럽]

     

    SQL 4주차 강의 노트정리[국비지원_스파르타 코딩클럽]

    스파르타 코딩클럽 SQL 4주차 강의 '핵심' 노트정리 1. Subquery 개념 : Subquery(서브쿼리)는 하나의 SQL쿼리 안에 또 다른 SQL쿼리가 있는 것. ex. kakaopay로 결제한 유저들의 정보 보기(users테이블과 orders

    nasena.tistory.com

     

    그런데 당시에 서브쿼리를 도대체 어디에 써야 하는가를 고민했던 것은

    SQL이 조금 익숙해진 지금에 와서 보니 그렇게 중요한 것은 아니었다.

     

    서브쿼리가 필요한 경우는, 

    해결해야 할 문제를 보니 내가 여러 번의 연산을 수행해야 된다.

    ② 그런데 이전의 연산 결과를 다음 연산에 이용해야 한다.

    이럴 때이다. 

     

    서브쿼리의 결과를 단순히 조회하고 싶으면 SELECT문에 적고,

    서브쿼리의 결과를 조건문의 조건식 중 하나로 넣고 싶으면 WEHRE절에 넣고,

    서브쿼리의 결과를 하나의 테이블로 간주해 다시 거기서 조건에 따른 결과를 조회해 보고 싶으면 FROM절에 넣으면 된다.

    필요하다면 이 결과를 다시 서브쿼리로 SELECT절, WHERE절, FROM절에 넣어 사용할 수 있다.

     

    그럼 서브쿼리에 대해 실습문제 쿼리문을 보며 다시 자세히 알아보자.


    1. 서브쿼리(Subquery) 집중 탐구

     

    1-1) 서브쿼리(Subquery) 

     

    ▶ 서브쿼리문의 기본 구조

    - FROM절 서브쿼리

    SELECT column1, special_column
    FROM
        ( /* subquery */
        SELECT column1, column2 special_column
        FROM table1
        ) a

     

    - WEHRE절 서브쿼리

    SELECT column1, column2
    FROM table1
    WHERE column1 = (SELECT col1 FROM table2)

     

     

    1-2) 서브쿼리(Subquery) 실습문제

     

    문제1) 음식 주문 시간이 25분보다 초과한 시간 가져오기

    : food_preparation_time(음식 주문 시간)이 25분보다 초과한 시간을 구하고 over_time이라고 이름 붙여줌

    : 이 결과를 FROM절의 서브쿼리로 넣어줌

    : 이 FROM절 결과를 이용해서, IF문으로 음식 주문 시간이 25분을 초과하지 않은 값들은 0으로 간주한 뒤 조회함

    SELECT order_id, 
           restaurant_name, 
           IF(over_time > 0, over_time, 0) over_time
    FROM 
    (
    SELECT order_id, restaurant_name, (food_preparation_time-25) over_time
    FROM food_orders
    ) a

     

     

    ▶ CASE문으로도 풀 수 있음

    (모든 문제를 서브쿼리로 풀 필요는 없음. 간단하게 풀 수 있는 문제는 간단하게 풀기!)

    SELECT order_id ,
           restaurant_name ,
           food_preparation_time ,
           CASE WHEN food_preparation_time <= 25 THEN 0
                WHEN food_preparation_time > 25 THEN food_preparation_time - 25
           END over_time
    FROM food_orders fo

     


     

    조건문과 Subquery를 결합하여 User Segmentation과 연산 해보기

     

    문제2) 음식점의 평균 단가별 segmentaion을 진행하고, 그룹에 따라 수수료 연산하기

     

    ⓛ 첫 번째 과정_ 음식점 별 평균 음식단가 구하기

    : 일단 restaurant_name(음식점 명) 별평균 unit_cost(음식 단가)를 구함

    SELECT order_id ,
            restaurant_name ,
            AVG(price/quantity) unit_cost
    FROM food_orders fo 
    Group By restaurant_name

     

     

    ②두 번째 과정_평균 음식 단가로 수수료 segmentation 하기

    : 첫 번째 과정의 결과를 FROM절의 서브쿼리로 넣어줌.

    : 그 뒤 평균 unit_cost(음식 단가) 별 vat(수수료)를 산정해 줌. 

    SELECT order_id,
           restaurant_name,
           unit_cost,
           CASE WHEN unit_cost < 5000 THEN '0.5%'
                WHEN unit_cost < 20000 THEN '1%'
                WHEN unit_cost < 30000 THEN '2%'
                ELSE '3%'
           END vat
    FROM
    (SELECT order_id ,
            restaurant_name ,
            AVG(price/quantity) unit_cost
    FROM food_orders fo 
    Group By restaurant_name) a

     

     

    ③ 최종_ 수수료가 적용된 평균 음식 단가 구하기(평균 음식단가 * 수수료)

    : 두 번째 과정의 결과를 다시 FROM절의 서브쿼리로 넣어줌.

    : 그 후 수수료가 적용된 평균 음식 단가를 마지막으로 조회해줌.

    SELECT order_id,
           restaurant_name,
           unit_cost * vat  apply_vat_price
    FROM 
    (SELECT order_id,
           restaurant_name,
           unit_cost,
           CASE WHEN unit_cost < 5000 THEN '0.5%'
                WHEN unit_cost < 20000 THEN '1%'
                WHEN unit_cost < 30000 THEN '2%'
                ELSE '3%'
           END vat
    FROM
    (SELECT order_id ,
            restaurant_name ,
            AVG(price/quantity) unit_cost
    FROM food_orders fo 
    Group By restaurant_name) a) b

     


     

    심화1) 음식점의 총 주문 수량과 총 주문금액을 계산하고, 주문 수량을 기반으로 수수료 할인율 구하기

    - 총 주문 수량 5개 이하: 0.5% 할인

    - 총 주문 수량 15개 초과, 총 주문 금액 300,000원 이상: 10% 할인

    - 그 외: 일괄 1% 

    SELECT restaurant_name,
           CASE WHEN total_quantity <= 5 then 0.005
                WHEN total_quantity > 15 AND total_price >= 300000 THEN 0.1
                ELSE 0.01
           END vat_discount 
    FROM  
    (SELECT restaurant_name,
            sum(quantity) total_quantity,
            sum(price) total_price
    FROM food_orders fo 
    Group By 1) a

     

     

    서브쿼리 문제를 잘 푸는 방법

    문제를 천천히 뜯어보면서 먼저 문제를 세분화 해보고, 

    세분화한 문제 중 먼저 풀어야 할 문제를 골라 연산한 뒤 조회해주고,

    연산 결과를 다음 풀어야 할 문제의 쿼리문에 서브쿼리로 넣어주는 걸 반복하면 됩니다.

    별로 안 어렵쥬..?  (아마..도요.?)

    728x90

    댓글