취업준비/코딩테스트 문제 풀이

[프로그래머스 SQL 코딩테스트 연습] Lv4. 주문량이 많은 아이스크림들 조회하기 (MySQL)

상급닌자연습생 2024. 6. 21. 15:54

🤔 문제

다음은 아이스크림 가게의 상반기 주문 정보를 담은 `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

 

[프로그래머스/SQL] 주문량이 많은 아이스크림들 조회하기

https://school.programmers.co.kr/learn/courses/30/lessons/133027 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞

eunsun-zizone-zzang.tistory.com

 

 

 

[다른 풀이 2번 참고]

https://jun-bae.tistory.com/77

 

[Programmers Lv.4] 주문량이 많은 아이스크림들 조회하기 (MySQL)

https://school.programmers.co.kr/learn/courses/30/lessons/133027 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞

jun-bae.tistory.com

 

 

 

[다른 풀이 3번 참고]

https://velog.io/@zinu/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A3%BC%EB%AC%B8%EB%9F%89%EC%9D%B4-%EB%A7%8E%EC%9D%80-%EC%95%84%EC%9D%B4%EC%8A%A4%ED%81%AC%EB%A6%BC%EB%93%A4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0MySQLJOIN#-%EB%8B%A4%EB%A5%B8-%ED%92%80%EC%9D%B4

 

프로그래머스 - 주문량이 많은 아이스크림들 조회하기(MySQL,JOIN)

\*\*<span style="color:<span style="color:- <span style="color:- \*\*<span style="color:\*\*<span style="color:

velog.io