[프로그래머스/MySQL/JOIN/LV.4] 주문량이 많은 아이스크림들 조회하기

sammy·2024년 6월 19일

SQL 문제풀이

목록 보기
23/87

문제

문제 설명

다음은 아이스크림 가게의 상반기 주문 정보를 담은 FIRST_HALF 테이블과 7월의 아이스크림 주문 정보를 담은 JULY 테이블입니다. FIRST_HALF 테이블 구조는 다음과 같으며, SHIPMENT_ID, FLAVOR, TOTAL_ORDER는 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 상반기 아이스크림 총주문량을 나타냅니다. FIRST_HALF 테이블의 기본 키는 FLAVOR입니다. FIRST_HALF테이블의 SHIPMENT_IDJULY테이블의 SHIPMENT_ID의 외래 키입니다.

NAME TYPE NULLABLE
SHIPMENT_ID INT(N) FALSE
FLAVOR VARCHAR(N) FALSE
TOTAL_ORDER INT(N) FALSE

JULY 테이블 구조는 다음과 같으며, SHIPMENT_ID, FLAVOR, TOTAL_ORDER 은 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 7월 아이스크림 총주문량을 나타냅니다. JULY 테이블의 기본 키는 SHIPMENT_ID입니다. JULY테이블의 FLAVORFIRST_HALF 테이블의 FLAVOR의 외래 키입니다. 7월에는 아이스크림 주문량이 많아 같은 아이스크림에 대하여 서로 다른 두 공장에서 아이스크림 가게로 출하를 진행하는 경우가 있습니다. 이 경우 같은 맛의 아이스크림이라도 다른 출하 번호를 갖게 됩니다.

NAME TYPE NULLABLE
SHIPMENT_ID INT(N) FALSE
FLAVOR VARCHAR(N) FALSE
TOTAL_ORDER INT(N) FALSE

문제

7월 아이스크림 총 주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회하는 SQL 문을 작성해주세요.


예시

예를 들어 FIRST_HALF 테이블이 다음과 같고

SHIPMENT_ID FLAVOR TOTAL_ORDER
101 chocolate 3200
102 vanilla 2800
103 mint_chocolate 1700
104 caramel 2600
105 white_chocolate 3100
106 peach 2450
107 watermelon 2150
108 mango 2900
109 strawberry 3100
110 melon 3150
111 orange 2900
112 pineapple 2900

JULY테이블이 다음과 같다면

SHIPMENT_ID FLAVOR TOTAL_ORDER
101 chocolate 520
102 vanilla 560
103 mint_chocolate 400
104 caramel 460
105 white_chocolate 350
106 peach 500
107 watermelon 780
108 mango 790
109 strawberry 520
110 melon 400
111 orange 250
112 pineapple 200
208 mango 110
209 strawberry 220

7월 아이스크림 총주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회하면 strawberry(520 + 220 + 3,100 = 3,840), mango(790 + 110 + 2,900 = 3,800), chocolate(520 + 3,200 = 3,720) 순입니다. 따라서 SQL 문을 실행하면 다음과 같이 나와야 합니다.

FLAVOR
strawberry
mango
chocolate

✔️  문제접근

  • FIRST_HALF 테이블과 JULYUNION하는 서브쿼리를 하나 만든다.
  • 위 서브쿼리를 FROM 절에 넣고, FLAVORGROUP BY 하여 TOTAL_ORDER의 총합을 구해주는 서브쿼리를 만든다.
  • 위 서브쿼리를 다시 주 쿼리의 FROM 절에 넣고, 내림차순으로 ORDER BY 후, LIMIT 키워드를 통해 상위 3개의 맛만 출력한다.

⭐️   내 정답

SELECT FLAVOR
FROM (
    SELECT FLAVOR, SUM(TOTAL_ORDER) AS TOTAL_ORDER_SUM
    FROM (
        SELECT FLAVOR, TOTAL_ORDER FROM FIRST_HALF
        UNION ALL
        SELECT FLAVOR, TOTAL_ORDER FROM JULY
    ) AS UNION_TABLE
    GROUP BY FLAVOR
) AS UNION_GROUP_TABLE
ORDER BY TOTAL_ORDER_SUM DESC LIMIT 3;

🔎  짚고 넘어가기

UNION vs UNION ALL

UNIONUNION ALL은 SQL에서 두 개 이상의 SELECT 문을 결합하는 데 사용되는 연산자입니다.

UNION

  • 중복 제거: UNION 연산자는 두 개 이상의 SELECT 문에서 반환된 결과를 결합하고, 중복된 행을 제거합니다.
  • 정렬: UNION은 결과 집합을 정렬하여 중복된 행을 제거합니다. 이로 인해 성능이 저하될 수 있습니다.
  • 사용 예: 중복된 행을 포함하지 않는 고유한 결과 집합이 필요할 때 사용합니다.
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;

UNION ALL

  • 중복 허용: UNION ALL 연산자는 두 개 이상의 SELECT 문에서 반환된 결과를 결합하지만, 중복된 행을 제거하지 않습니다.
  • 성능: UNION ALL은 중복을 제거하지 않기 때문에 정렬 작업이 필요 없으며, 따라서 UNION보다 성능이 더 좋습니다.
  • 사용 예: 중복된 행을 포함하여 모든 결과를 결합하고자 할 때 사용합니다.
SELECT column1, column2 FROM table1
UNION ALL
SELECT column1, column2 FROM table2;

차이점

  1. 중복 처리:

    • UNION은 중복된 행을 제거합니다.
    • UNION ALL은 중복된 행을 포함합니다.
  2. 성능:

    • UNION은 중복 제거를 위해 정렬이 필요하므로 더 느립니다.
    • UNION ALL은 중복 제거를 하지 않으므로 더 빠릅니다.
  3. 사용 목적:

    • UNION은 고유한 결과 집합이 필요할 때 사용합니다.
    • UNION ALL은 중복을 포함한 모든 결과가 필요할 때 사용합니다.

예제

테이블 예시

-- 테이블1 (table1)
SELECT * FROM table1;

ID | Name
---|-----
1  | Alice
2  | Bob
3  | Carol

-- 테이블2 (table2)
SELECT * FROM table2;

ID | Name
---|-----
2  | Bob
3  | Carol
4  | Dave

UNION 예제

SELECT ID, Name FROM table1
UNION
SELECT ID, Name FROM table2;

결과

IDName
1Alice
2Bob
3Carol
4Dave

UNION ALL 예제

SELECT ID, Name FROM table1
UNION ALL
SELECT ID, Name FROM table2;

결과

IDName
1Alice
2Bob
3Carol
2Bob
3Carol
4Dave

위 예제에서 볼 수 있듯이, UNION은 중복된 행을 제거한 고유한 결과를 반환하고, UNION ALL은 중복된 행을 포함하여 모든 결과를 반환합니다.

profile
누군가에게 도움을 주기 위한 개발자로 성장하고 싶습니다.

0개의 댓글