본문 바로가기
SQL 문제 풀기/1. 프로그래머스 SQL : 2023.12.17~2024.2.29

<프로그래머스 63> 식품분류별 가장 비싼 식품의 정보 조회하기(Lv.4)

by HYEHYE_SON 2024. 2. 17.
728x90

 

프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지


 

 

문제 설명

다음은 식품의 정보를 담은 FOOD_PRODUCT 테이블입니다. FOOD_PRODUCT 테이블은 다음과 같으며 PRODUCT_IDPRODUCT_NAMEPRODUCT_CDCATEGORYPRICE는 식품 ID, 식품 이름, 식품코드, 식품분류, 식품 가격을 의미합니다

 

Column name Type Nullable
PRODUCT_ID VARCHAR(10) FALSE
PRODUCT_NAME VARCHAR(50) FALSE
PRODUCT_CD VARCHAR(10) TRUE
CATEGORY VARCHAR(10) TRUE
PRICE NUMBER TRUE

문제

FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회하는 SQL문을 작성해주세요. 이때 식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력시켜 주시고 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.

예시

FOOD_PRODUCT 테이블이 다음과 같을 때

PRODUCT_ID PRODUCT_NAME PRODUCT_CD CATEGORY PRICE
P0018 맛있는고추기름 CD_OL00008 식용유 6100
P0019 맛있는카놀라유 CD_OL00009 식용유 5100
P0020 맛있는산초유 CD_OL00010 식용유 6500
P0021 맛있는케첩 CD_SC00001 소스 4500
P0022 맛있는마요네즈 CD_SC00002 소스 4700
P0039 맛있는황도 CD_CN00008 4100
P0040 맛있는명이나물 CD_CN00009 3500
P0041 맛있는보리차 CD_TE00010 3400
P0042 맛있는메밀차 CD_TE00001 3500
P0099 맛있는맛동산 CD_CK00002 과자 1800

 

SQL을 실행하면 다음과 같이 출력되어야 합니다.

CATEGORY MAX_PRICE PRODUCT_NAME
식용유 6500 맛있는산초유
과자 1800 맛있는맛동산

♥ 정답

select category, price as max_price, product_name
    from (select category, product_name, price, 
          rank() over (partition by category order by price desc ) as rnk
          from food_product) d
    where category in ('과자', '국', '김치', '식용유')
     and rnk = 1
    order by max_price desc;

 

 

이 문제는 
in line view (FROM절의 서브쿼리)와 RANK 윈도우함수
위 2가지를 사용하여 해결하였다.

 


■ EQUI JOIN

조인은 여러 개의 테이블의 컬럼들을 활용하여 한 번에 원하는 것을 출력하고자 할 때 사용하는 문법이다.

그 중 EQUI JOIN 이란, 

조인하려는 테이블 사이에 공통된 컬럼이 있을 경우 (컬럼명은 달라도 되고, 데이터가 공통될 때)

EQUAL(=) 조인하는 조인 문법이다.

 

ORACLE과 MySQL의 차이점은

MySQL에서는 IN LINE VIEW에 별칭을 지정해줘야 오류가 발생하지 않는 것이다.

ORACLE은 별칭이 없어도 에러가 발생하지 않았다.

 

■ 윈도우 함수(Window function)

윈도우 함수는 특정 창(Window) 또는 그룹 내에서 데이터를 처리하고 계산하는 데 사용된다.
일반적으로 집계 함수와는 달리 개별 행에 대한 계산을 수행하며
데이터 집합을 여러 그룹으로 나눌 필요 없이 전체 데이터 집합에 대해 작동한다.

윈도우 함수는 OVER절을 사용하여 정의하고, 윈도우의 파티션(분할 기준), 정렬 순서(ORDER BY), 윈도우 프레임(계산 대상 행의 범위) 등을 지정할 수 있다. 
주로 아래와 같은 상황에서 사용한다.
-  순위를 계산하는 함수 : RANK(), DENSE_RANK(), ROW_NUMBER() 등
-  누적 합, 평균, 최소값, 최대값 계산: `SUM()`, `AVG()`, `MIN()`, `MAX()` 등

 

 


 해설해보기

 #IN LINE VIEW 

 

메인쿼리에서 출력되어야할 컬럼명들을 나열해주고,

마지막에 순위를 구하기 위해서 RANK() 윈도우함수를 사용해준다.

CATEGORY 별 순위를 구해야하기 때문에 PARTITION 을 CATEGORY  별로 나누어주고, 

가장 비싼 식품의 가격을 조회해야 하기 때문에 PRICE컬럼을 기준으로 DESC하게 정렬해준다.

마지막으로 메인쿼리에서 사용하기 위해서 별칭을 지정해준다.

 

rank() over (partition by category order by price desc) rnk

 

 

 

 #MAIN QUERY 

 

IN LINE VIEW 에서 출력된 결과는 

FOOD_PRODUCT 테이블에서 식품분류별로 가격의 순위를 구한 RNK와

CATEGORY, PRODUCT_NAME, PRICE 이다.

 

위 결과를 가지고 문제의 요구를 충족하기 위해 분류, 가격, 이름을 조회하기 위해 아래와 같이 SELECT절을 작성한다.

 

SELECT category, price as max_price, product_name

 

max_price로 설정된 컬럼을 충족하기 위해서 

in line view에서 생성했던 식품분류별 가격 순위 컬럼인 rnk를 활용하여 where절에서 rnk=1로 제한해준다.

이렇게 되면 식품분류별 가격이 제일 비싼 식품에 대해서만 조회할 수 있다.

 

추가적으로 식품분류는 '과자', '국', '김치', '식용유'인 경우만 출력되어야하기 때문에 in을 사용하여 제한해준다.

 

WHERE category in ('과자', '국', '김치', '식용유')

 

마지막으로 max_price를 기준으로 desc하게 정렬해준다.


결과 출력

 

 

 

 

 

 

출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges

반응형