SQL 예제 정리('주문량이 많은 아이스크림들 조회하기')(24.05.04)
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의 차이점을 알고 있어야 하는데요,
UNION은 A테이블과 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 절에서도 집계함수를 사용할 수 있다는 점을 유념해야겠습니다.