코딩테스트/SQL

[프로그래머스][MySQL] Lv. 4 식품분류별 가장 비싼 식품의 정보 조회하기

_알파카 2024. 7. 29. 17:48
728x90

문제 설명

https://school.programmers.co.kr/learn/courses/30/lessons/131116

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

시도 1 (틀린 풀이)

SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
GROUP BY CATEGORY
ORDER BY MAX(PRICE) DESC

 

처음에는 복잡하지 않게 생각하고 풀어보았다. 그러나, 이 풀이는 틀렸다ㅠㅠ

 

이유는, GROUP BY와 SELECT 절의 조합 때문이다. 

GROUP BY를 사용할 떄는 SELECT 절에서 그룹화되지 않은 열은 집계 함수와 함께 사용할 수 없다. 

즉, CATEGORY 열과  MAX(PRICE)는 그룹화되고 있지만, PRODUCT_NAME은 그룹화되지 않고 있다. 

 

실제로, 과자 카테고리에서 금액이 가장 큰 제품은 '맛있는허니버터칩'으로, 1950원을 나타내고 있지만, 

위의 쿼리로 실행한 결과를 아래와 같이 나오게 된다. 

 

즉, 카테고리에 따른 가장 큰 금액은 올바르게 도출되지만, 제품 이름(PRODUCT_NAME)이 제대로 출력되지 않고 있다. 

 

정답 풀이

풀이 1

SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE (CATEGORY, PRICE) IN (
    SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE
    FROM FOOD_PRODUCT
    WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
    GROUP BY CATEGORY
)
ORDER BY PRICE DESC;

 

앞서 첫 번째 시도를 바탕으로 구한 쿼리이다. 

먼저, 서브쿼리를 통해 각 카테고리에서 가장 높은 가격을 찾는다. 

이 가격 값을 본 테이블에서 찾아, 최대 가격에 해당하는 행을 찾아내는 것이다. 

 

풀이 2

아래는 CTE 구문을 이용해서 풀어본 것이다. 

위의 쿼리와 마찬가지로 CTE를 이용해 카테고리에 따른 최대 가격을 구하고, 

이를 본래 테이블과 JOIN하여 원하는 값을 뽑아내는 것이다. 

WITH w1 AS (
    SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE
    FROM FOOD_PRODUCT
    WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
    GROUP BY CATEGORY
)
SELECT f.CATEGORY, f.PRICE AS MAX_PRICE, f.PRODUCT_NAME
FROM FOOD_PRODUCT f INNER JOIN w1
ON f.PRICE = w1.MAX_PRICE AND f.CATEGORY = w1.CATEGORY
ORDER BY PRICE DESC;

 

 

풀이 3

WITH w1 AS (
    SELECT *, RANK() OVER(PARTITION BY CATEGORY ORDER BY PRICE DESC) AS max_price
    FROM FOOD_PRODUCT
    WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
)
SELECT f.CATEGORY, f.PRICE AS MAX_PRICE, f.PRODUCT_NAME
FROM FOOD_PRODUCT f INNER JOIN w1
ON f.PRODUCT_ID = w1.PRODUCT_ID
WHERE w1.max_price = 1
ORDER BY f.PRICE DESC;

 

윈도우 함수(RANK)함수를 사용하여, 가격의 순위를 매기는 함수이다. 

전체적인 코드는 위와 비슷하다!  

 

 

728x90