세조목

SQL 예제 정리('주문량이 많은 아이스크림들 조회하기')(24.05.04) 본문

데이터 분석 공부/SQL

SQL 예제 정리('주문량이 많은 아이스크림들 조회하기')(24.05.04)

세조목 2024. 5. 4. 22:14

https://school.programmers.co.kr/learn/courses/30/lessons/133027

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제의 요구사항은 상반기와 7월의 FLAVOR별 총 주문량 합 TOP.3를 뽑는겁니다.

일단 상반기의 TOTAL_ORDER와 7월의 TOTAL_ORDER를 합해야 하는데

어떻게 합해야 할까요?

JOIN시키면 오른쪽으로 붙으니까 FLAVOR별 주문량 합계를 구할 수 없으니

아래쪽으로 붙여야겠습니다.

이 때 사용하는 기능이 'UNION'입니다.

UNION은 A테이블 아래쪽에 B테이블을 붙이는겁니다.

그렇다보니 A, B테이블은 컬럼의 수와 컬럼명이 동일해야합니다.

예를 들어 아래와 같은 두 개의 테이블을 UNION 시키면

 

아래와 같이 합쳐집니다.

SHIPMENT_ID FLAVOR TOTAL_ORDER
101 chocolate 3200
101 chocolate 520
102 vanilla 2800
102 vanilla 560
103 mint_chocolate 1700
103 mint_chocolate 400
104 caramel 2600
104 caramel 460
105 white_chocolate 350
106 peach 500

 

SELECT MERGED_TABLE.FLAVOR, MERGED_TABLE.TOTAL_ORDER
FROM
    (
    SELECT *
    FROM FIRST_HALF

    UNION ALL

    SELECT *
    FROM JULY
    ) MERGED_TABLE
GROUP BY MERGED_TABLE.FLAVOR
HAVING SUM(MERGED_TABLE.TOTAL_ORDER)
ORDER BY SUM(MERGED_TABLE.TOTAL_ORDER) DESC
LIMIT 3;

서브쿼리에 UNION 시킨 테이블들을 넣주고,

본 쿼리에서 FLAVOR별 TOTAL_ORDER의 SUM을 구해준 후,

TOTAL_ORDER 순서대로 정렬된 결과값 中 3개만 LIMIT을 걸어주면 됩니다.

 

그런데 설명에서는 UINON이라고 했는데

왜 쿼리문에서는 UNION ALL을 쓴걸까요?

질문에 답하기위해서는 UNION과 UNION ALL의 차이점을 알고 있어야 하는데요,

UNIONA테이블과 B테이블의 중복되는 값을 제거하지만

UNION ALL은 제거하지 않고 전부(ALL) 출력합니다.

문제에서의 경우 'FIRST_HALF' 테이블과 'JULY' 테이블에서 FLAVOR별로 중복되는 값이 없기 때문에

UNION을 쓰든 UNION ALL을 쓰든 상관없는 것입니다.

 

그리고 이 쿼리문에서 한 가지 더 짚고 넘어갈 점이 있습니다.

GROUP BY MERGED_TABLE.FLAVOR
HAVING SUM(MERGED_TABLE.TOTAL_ORDER)
ORDER BY SUM(MERGED_TABLE.TOTAL_ORDER) DESC
LIMIT 3;

저는 쿼리문을 작성할 때 GROUP BY로 GROUP화하고,

HAVING 절에서 TOTAL_ORDER를 SUM한 후,

ORDER BY 절에서 TOTAL_ORDER가 많은 순서대로 정렬했는데

사실 HAVING 절은 필요가 없습니다.

 

GROUP BY MERGED_TABLE.FLAVOR
ORDER BY SUM(MERGED_TABLE.TOTAL_ORDER) DESC
LIMIT 3;

이렇게 ORDER BY 절에서 집계함수를 사용할 수 있기 때문입니다.

ORDER BY 절에서도 집계함수를 사용할 수 있다는 점을 유념해야겠습니다.