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


처음에 첫번째 문제를 봤을 때는 뭔가 group by 로 잘 묶고 having 을 잘 쓰면 될 것 같았다.
근데 단순히 having에 조건절 하나 넣어서 풀려고 하니까 마땅한 답이 생각나지 않았다.
그래서 검색을 좀 해봤더니 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의 대체재로 쓴 것 같아 찜찜한 상태로 넘어갔다.
그런데 오늘 또 유사한 문제가 나왔고 어제 찜찜했던 점을 바탕으로 검색을 좀 해봤다.
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은 결과는 같아도 실제 동작에서 성능 차이가 많이 날 수 있으므로 결과만 보지 말고 더 나은 답은 없는지 잘 알아봐야겠다.