프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지
문제 설명
다음은 아이스크림 가게의 상반기 주문 정보를 담은 FIRST_HALF 테이블과 7월의 아이스크림 주문 정보를 담은 JULY 테이블입니다. FIRST_HALF 테이블 구조는 다음과 같으며, SHIPMENT_ID, FLAVOR, TOTAL_ORDER는 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 상반기 아이스크림 총주문량을 나타냅니다. FIRST_HALF 테이블의 기본 키는 FLAVOR입니다. FIRST_HALF테이블의 SHIPMENT_ID는 JULY테이블의 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테이블의 FLAVOR는 FIRST_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 테이블이 다음과 같고
[ 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테이블이 다음과 같다면
[ 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 |
♥ 오라클 정답
select d.flavor
from( select j.flavor, sum(j.total_order + f.total_order) sum_order
from july j, first_half f
where j.flavor=f.flavor
group by j.flavor
order by sum_order desc fetch first 3 rows only) d;
♥ MySQL 정답
select d.flavor
from( select j.flavor, sum(j.total_order + f.total_order) sum_order
from july j, first_half f
where j.flavor=f.flavor
group by j.flavor
order by sum_order desc limit 3) d;
■ EQUI JOIN
조인은 여러 개의 테이블의 컬럼들을 활용하여 한 번에 원하는 것을 출력하고자 할 때 사용하는 문법이다.
그 중 EQUI JOIN 이란,
조인하려는 테이블 사이에 공통된 컬럼이 있을 경우 (컬럼명은 달라도 되고, 데이터가 공통될 때)
EQUAL(=) 조인하는 조인 문법이다.
ORACLE과 MySQL의 차이점은
MySQL에서는 IN LINE VIEW에 별칭을 지정해줘야 오류가 발생하지 않는 것이다.
ORACLE은 별칭이 없어도 에러가 발생하지 않았다.
■ ORDER BY절에서 FETCH FIRST 사용 - Oracle
정렬된 결과 중 반환될 행의 수를 제한해 줄 때 사용한다.
순서대로 정렬된 값 중 맨 위의 값에서 부터
연속적인 특정 값들중 몇 개만 출력할 때 사용할 수 있다.
- order by [정렬할 컬럼명] asc/desc FETCH FIRST [숫자] ROWS ONLY
숫자 부분에 원하는 수를 넣으면,
정렬된 데이터 중 위에서 부터 몇개의 행을 출력할 것인지 지정할 수 있다.
예를 들어 아래와 같이 입력했다면,
order by datetime asc fetch first 1 rows only;
가장 오래 보호소에 있었던 동물 1마리의 이름과 보호 시작일을 조회하게된다.
■ LIMIT 함수 - MySQL
쿼리 결과에서 반환되는 행의 수를 제한하는 데 사용되는 함수
주로 일부 결과만 필요한 경우에 사용된다.
- LIMIT [처음부터 시작해서 반환할 행의 수 ]
- LIMIT [반환할 행의 시작위치(0부터 시작)], [반환할 행의 수]
정답 해설
이 문제는 인라인뷰를 사용하는데, 그 안에 들어갈 쿼리문은 아래와 같아
아이스크림 맛 별 7월 아이스크림의 총주문량과 상반기 아이스크림의 총 주문량을 더한 값이
큰 순서대로 상위 3개의 맛을 조회하는 쿼리는 작성해준다.
후에 그 결과를 가지고 FLAVOR를 조회해주면 된다.
# 1. IN LINE VIEW
여기서 중요한 것은
아이스크림 맛 별 7월 아이스크림의 총주문량과
상반기 아이스크림의 총 주문량을 더한 값을 출력하는 것이다.
그러기 위해선 우선 두 개의 테이블을 조인해줘야한다.
이때 공통된 컬럼인 flavor를 가지고 equi join해준다.
조인으로 각 테이블의 컬럼을 가져올 수 있게 되면 총 주문량 생성해야한다.
총 주문량은 july테이블의 total_order와 first_half 테이블의 total_order를 더해서 생성해야 한다.
그룹함수 sum을 사용해주기 위해서는 group by를 해주어야 한다.
따라서 맛 별 총 주문량을 구하기 위해
group by절에 j.flavor 컬럼을 넣어준다.
-- ORDER BY 절
상위 3개의 맛을 추출하기 위해서
sum_order 를 기준으로 큰 값이 위로 올 수 있게 desc하게 정렬해준다.
그 상위 3개의 값만 추출하기 위해서
* MySQL : limit3 를 넣어준다.
* Oracle : fetch first 3 rows only;
# 2. IN LINE VIEW
총 주문량의 값이 상위 3개의 데이터에 대해서
맛(flavor)만 출력하기 위함
출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
'SQL 문제 풀기 > 1. 프로그래머스 SQL : 2023.12.17~2024.2.29' 카테고리의 다른 글
<프로그래머스 72> 오프라인/온라인 판매 데이터 통합하기(Lv.4) (0) | 2024.02.26 |
---|---|
<프로그래머스 71> 그룹별 조건에 맞는 식당 목록 출력하기(Lv.4) (2) | 2024.02.25 |
<프로그래머스 69> 우유와 요거트가 담긴 장바구니(Lv.4) (0) | 2024.02.23 |
<프로그래머스 68> 저자 별 카테고리 별 매출액 집계하기(Lv.4) (0) | 2024.02.22 |
<프로그래머스 67> 년, 월, 성별 별 상품 구매 회원 수 구하기(Lv.4) (0) | 2024.02.21 |