[프로그래머스 SQL 코딩테스트 연습] Lv4. 주문량이 많은 아이스크림들 조회하기 (MySQL)
🤔 문제
다음은 아이스크림 가게의 상반기 주문 정보를 담은 `FIRST_HALF` 테이블과 7월의 아이스크림 주문 정보를 담은 `JULY` 테이블입니다. `FIRST_HALF` 테이블 구조는 다음과 같으며, `SHIPMENT_ID`, `FLAVOR`, `TOTAL_ORDER`는 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 상반기 아이스크림 총주문량을 나타냅니다. `FIRST_HALF` 테이블의 기본 키는 FLAVOR입니다. `FIRST_HALF`테이블의 `SHIPMENT_ID`는 `JULY` 테이블의 `SHIPMENT_ID`의 외래 키입니다.
`JULY` 테이블 구조는 다음과 같으며, `SHIPMENT_ID`, `FLAVOR`, `TOTAL_ORDER` 은 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 7월 아이스크림 총주문량을 나타냅니다. `JULY` 테이블의 기본 키는 `SHIPMENT_ID`입니다. `JULY`테이블의 `FLAVOR`는 `FIRST_HALF` 테이블의 `FLAVOR`의 외래 키입니다. 7월에는 아이스크림 주문량이 많아 같은 아이스크림에 대하여 서로 다른 두 공장에서 아이스크림 가게로 출하를 진행하는 경우가 있습니다. 이 경우 같은 맛의 아이스크림이라도 다른 출하 번호를 갖게 됩니다.
7월 아이스크림 총 주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회하는 SQL 문을 작성해주세요.
예시
예를 들어 `FIRST_HALF` 테이블이 다음과 같고
`JULY` 테이블이 다음과 같다면
7월 아이스크림 총주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회하면 strawberry(520 + 220 + 3,100 = 3,840), mango(790 + 110 + 2,900 = 3,800), chocolate(520 + 3,200 = 3,720) 순입니다. 따라서 SQL 문을 실행하면 다음과 같이 나와야 합니다.
💻 나의 풀이
WITH JULY_ORDER AS( -- 7월 아이스크림 주문량 합산
SELECT FLAVOR, SUM(TOTAL_ORDER) AS TOTAL_ORDER_JULY
FROM JULY
GROUP BY FLAVOR
),
TOTAL AS( -- 상반기 + 7월 아이스크림 주문량 합산
SELECT f.FLAVOR, (f.TOTAL_ORDER + j.TOTAL_ORDER_JULY) AS TOTAL_ORDER
FROM FIRST_HALF f
JOIN JULY_ORDER j ON f.FLAVOR=j.FLAVOR
ORDER BY 2 DESC
LIMIT 3 -- 상위 3개만 추출
)
SELECT FLAVOR
FROM TOTAL;
결과
정답이긴 한데 좀 더 간단한 풀이가 있을 것 같아서 다른 사람 풀이를 찾아보았다.
💡 다른 풀이
1. 서브 쿼리에 직접 INNER JOIN 한 방법
SELECT F.FLAVOR
FROM FIRST_HALF F
INNER JOIN (SELECT FLAVOR, SUM(TOTAL_ORDER) AS JULY_TOTAL_ORDER
FROM JULY
GROUP BY FLAVOR) J
ON F.FLAVOR = J.FLAVOR
ORDER BY TOTAL_ORDER + JULY_TOTAL_ORDER DESC
LIMIT 3;
1) 서브 쿼리로 7월 아이스크림 주문량 합산 테이블을 만들고, 해당 서브 쿼리에 직접 `INNER JOIN`했다.
2) 나처럼 상반기 + 7월 아이스크림 주문량 합산 테이블을 별도로 만들지 않고, `ORDER BY `절에 상반기와 7월 아이스크림 총 주문량을 기준으로 내림차순해서 쿼리를 간단히 만든 것 같다.
2. JOIN없이 UNION ALL을 활용한 방법
SELECT A.FLAVOR
FROM (
SELECT * FROM FIRST_HALF
UNION ALL
SELECT * FROM JULY
) AS A
GROUP BY A.FLAVOR
ORDER BY SUM(A.TOTAL_ORDER) DESC
LIMIT 3
1) `UNION ALL`은 두 개의 테이블을 합치면서 중복을 제거하지 않고 전부 조회한다. 그래서 상반기와 7월 주문량을 중복 제거 없이 전부 합쳐서 `A`라는 별칭으로 설정한다.
2) `FLAVOR`을 기준으로 그룹화한다.
3) 아이스크림 맛 별로 전체 총 주문량을 기준으로 내림차순 정렬 후 상위 3개만 추출한다.
3. ORDER BY절에서 전부 처리하는 방법
SELECT F.FLAVOR
FROM FIRST_HALF F
JOIN JULY J ON F.FLAVOR = J.FLAVOR
GROUP BY 1
ORDER BY SUM(F.TOTAL_ORDER) + SUM(J.TOTAL_ORDER) DESC
LIMIT 3;
1) `FLAVOR`을 기준으로 상반기와 7월 아이스크림 주문량 테이블을 `INNER JOIN`하고
2) `FLAVOR`로 그룹화 한 다음,
3) 상반기 아이스크림 총 주문량과 7월달 아이스크림 총 주문량을 합산한 값을 기준으로 내림차순 정렬하여 상위 3개만 추출한다.
► 3번 풀이가 가장 간단하고 깔끔한 풀이인 것 같다.
🔗 References
[다른 풀이 1번 참고]
https://eunsun-zizone-zzang.tistory.com/93
[다른 풀이 2번 참고]
https://jun-bae.tistory.com/77
[다른 풀이 3번 참고]