프로그래머스 131123, 131116

오지석·2024년 5월 21일

어제 오늘 풀었던 두 문제가 상당히 유사하다고 생각해서 묶어서 정리해놓기로 했다.

문제

131123
131116

생각했던 풀이

처음에 첫번째 문제를 봤을 때는 뭔가 group by 로 잘 묶고 having 을 잘 쓰면 될 것 같았다.
근데 단순히 having에 조건절 하나 넣어서 풀려고 하니까 마땅한 답이 생각나지 않았다.
그래서 검색을 좀 해봤더니 rank 라는 함수를 찾을 수 있었다.

rank

select food_type, rest_id, rest_name, favorites
from (SELECT food_type, rest_id, rest_name, favorites, 
    rank() over (
        partition by food_type 
        order by favorites desc) 
    as rank_no
from rest_info) as T
where rank_no = 1
order by food_type desc

food_type 별로 나누어 즐겨찾기 수의 랭크를 매기고 그 랭크가 1인 row만 뽑는 방식이다.
일단은 이렇게 써서 통과는 됐고 rank 자체를 제대로 썼다기 보단 뭔가 max의 대체재로 쓴 것 같아 찜찜한 상태로 넘어갔다.
그런데 오늘 또 유사한 문제가 나왔고 어제 찜찜했던 점을 바탕으로 검색을 좀 해봤다.

group by, max 서브쿼리

select category, price as max_price, product_name
from food_product
where (category, price) in (
    SELECT category, max(price) as price
    from food_product
    where category in ("과자", "국", "김치", "식용유")
    group by category
) order by price desc

where 절에서 비교를 할 때 저렇게 묶어서 비교를 할 수 있다는 사실을 잊고 있었다. 그리고 rank를 사용하면서 생기는 overhead도 줄일 수 있어 좋을 것 같다.
첫번째 문제도 비슷한 방식으로 group by와 max를 이용해서 쿼리를 짜면 다음과 같다.

select food_type, rest_id, rest_name, favorites
from rest_info
where (food_type, favorites) in (
    SELECT food_type, max(favorites) as favorites
    from rest_info
    group by food_type
) order by food_type desc

여담

sql은 결과는 같아도 실제 동작에서 성능 차이가 많이 날 수 있으므로 결과만 보지 말고 더 나은 답은 없는지 잘 알아봐야겠다.

0개의 댓글