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

우연히 구글링하다가 풀이를 먼저 발견한 문제인데

근본적으로 이렇게 풀면 안될 것 같은데? 하는 생각이 들어서 풀고 그 방법을 공유해본다.

🤔 문제

🔗

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

👊 풀이과정

각 카테고리 별로 가장 가격이 높은 식품의 정보를 조회하는 문제이다.

내가 보았던 풀이는 이런식이었다.

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

 

프로그래머스에 이 코드를 넣고 컴파일하면 정답 처리가 될 것이다.

하지만 이건 문제에 있던 테이블이 아주 적절하게 짜여 있었기 때문에 가능한 일이다.

 

다음과 같이 테이블을 만들고 위 코드로 질의해보았다.

 

국 카테고리에 대한 2개의 행이 조회되었다.

 

왜 이런 결과가 나타났을까?

바로 WHERE절 때문이다.

WHERE
	PRICE IN(SELECT MAX(PRICE) FROM FOOD_PRODUCT  GROUP BY CATEGORY)
	AND CATEGORY IN('과자', '국', '김치', '식용유')

PRICE IN()의 조건이 되는 값의 기준은 각 카테고리별 음식의 최고가를 서브쿼리로 받은 결과이다.

다시말해 식용유 카테고리의 최고가인 6500, 과자의 최고가인 1800, 국의 최고가인 6700 셋 중 하나와 일치하면 된다.

 

아까 뜬금없이 조회된 미역국을 보면 가격이 6500이다.

식용유 카테고리의 최고가와 일치하면서 PRICE IN() 조건을 충족해 얼떨결에 같이 조회된 것이다.

 

이 풀이방법은 특정 카테고리의 최고가가 다른 카테고리 식품의 가격과 일치하지 않는다는 조건 하에 유효함을 알 수 있다.

이는 CATEGORYMAX_VALUE 둘 중 하나만 일치하더라도 조회할 수 있도록 쿼리를 구성했기 때문이다.

모든 상황에서 적용하기 위해서는 두 컬럼의 조건을 모두 충족하는 행만 조회될 수 있도록 쿼리를 짜야 한다.

💻 소스코드

👉 IN() 사용

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

👉 LEFT JOIN 사용

SELECT A.*, B.PRODUCT_NAME
FROM
    (SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE
    FROM FOOD_PRODUCT
    GROUP BY CATEGORY
    HAVING CATEGORY IN('과자', '국', '김치', '식용유')) A
    LEFT JOIN
    (SELECT PRODUCT_NAME, PRICE, CATEGORY
    FROM FOOD_PRODUCT) B
    ON MAX_PRICE=PRICE AND A.CATEGORY=B.CATEGORY
ORDER BY MAX_PRICE DESC;