프로그래머스 MySQL 문제를 풀던 중, 학원에서 배웠던 서브 쿼리가 잘 기억나지 않아 다시 정리해보려 한다.
SELECT FOOD_TYPE, REST_ID, REST_NAME, MAX(FAVORITES) FROM REST_INFO
GROUP BY FOOD_TYPE
ORDER BY FAVORITES DESC;
처음에 이렇게 쿼리를 짰으나 오답이라고 나온다.
SQL에서 Group By 절은 MAX와 같은 집계 함수를 이용할 때 특정 그룹을 기준으로 수행하는데, Group By 절은 선택한 모든 컬럼에 적용되어야 한다.
즉, 쿼리에서 REST_ID와 REST_NAME을 Group By 절에 포함시키지 않았기 때문에 오류가 발생한 것이다.
또한, MAX(FAVORITES)를 이용하면 가장 많이 즐겨찾기 된 수를 찾을 수 있지만, 해당 식당의 REST_ID와 REST_NAME을 찾으려면 서브 쿼리나 JOIN을 이용해야 한다.
1. 서브 쿼리를 이용한 방법
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) IN
(SELECT FOOD_TYPE, MAX(FAVORITES)
FROM REST_INFO GROUP BY FOOD_TYPE)
ORDER BY FOOD_TYPE DESC;
-> 수정된 정답 쿼리
서브 쿼리의 결과가 WHERE (FOOD_TYPE, FAVORITES) IN의 (FOOD_TYPE, FAVORITES)에 담겨 메인 쿼리의 SELECT에 반환된다.
2. JOIN을 이용한 방법
SELECT A.FOOD_TYPE, A.REST_ID, A.REST_NAME, B.FAVORITES
FROM REST_INFO AS A
INNER JOIN (SELECT FOOD_TYPE, MAX(FAVORITES) AS FAVORITES
FROM REST_INFO
GROUP BY FOOD_TYPE) as B
ON A.FOOD_TYPE = B.FOOD_TYPE AND A.FAVORITES = B.FAVORITES
ORDER BY 1 DESC;
FAVORITES는 그룹별 max값이 잘 나오지만 REST_ID, REST_NAME은 그룹 조건에 없기 때문에 랜덤값이 나와 오류가 발생하기 때문에 INNER JOIN을 사용
두 쿼리 모두 동일한 결과를 반환하며, 어느 쪽이 "더 좋다"고 말하기는 어렵다. 어떤 쿼리를 사용할지는 주로 선호하는 스타일, 데이터베이스의 성능, 그리고 쿼리의 가독성에 따라 결정된다.
1. 서브쿼리와 IN 절을 사용한 쿼리
이 방법은 SQL의 기본적인 요소만을 사용하므로, 익숙하지 않은 사람들에게 이해하기 더 쉽다. 따라서 이해하고 디버깅하기 쉬울 수 있다. 그러나 IN 절은 큰 데이터셋에서 느릴 수 있다.
2. 조인을 사용한 쿼리
이 방법은 SQL의 조인 연산을 활용하므로, SQL에 익숙한 사람들에게는 이해하기 쉽다. 또한, 일반적으로 조인 연산은 IN 절보다 성능이 좋다.
'SQL' 카테고리의 다른 글
[MySQL] GROUP BY & HAVING (0) | 2023.12.06 |
---|---|
[MySQL] UNION(ALL) & JOIN (1) | 2023.11.30 |