오랜만에 서브쿼리 연습.
다른 참가자 분이 질문 채널에 올려주신
SQL 코드카타 48번 문제 관련.
기술적으로 엄밀히 맞는지는 모르겠지만
최대한 내가 이해한 범위 내에서 적어본다.
일반적으로 그룹별 데이터를 단순 조회할 때는
마지막에 group by로 묶어주면 끝이지만,
이 문제에서는
a. group by를 써서 그룹별로 데이터를 나눠 주고
b. 각 그룹별로 최대값 구하기
를 동시에 수행해야 한다.
이렇게 그루핑이 된 상태에서 연산을 할 경우
서브쿼리를 활용하면 해결할 수 있다.
서브쿼리를 안 쓰면 group by만 먹히고
각 그룹별 최대값이 안 구해진다. (이상한 결과가 출력됨)
나는 아래처럼 where 절 내에 서브쿼리를 넣어서 해결했다.
(좀 더 간결하게 같은 결과를 얻을 수 있는 방법이 있을까?)
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절 안이 좀 길어진 걸 빼면
기본적인 select ~ from where ~ order by 구조는 같다.
where 절만 더 찬찬히 뜯어보면,
where
①(food_type, favorites) in ②(
select
food_type,
max(favorites)
from
rest_info
group by
food_type
)
① food_type과 favorites가 ②에 해당하는 값이어야 한다
② 서브쿼리를 써서 food_type별 group by + 최대값을 불러온다
이 때 ②번만 따로 떼어서 쿼리를 실행시키면
아래와 같은 결과를 얻는다.
이미 서브쿼리 내에 group by가 있어서
food_type별 최대값이 불러와진 상태이므로,
본 쿼리에서는 따로 group by 처리를 할 필요가 없다.
서브쿼리를 포함해 쿼리 전체의 의미는 아래와 같다.
마치 긴 영어 문장 안에 독립된 의미를 갖는 '절'이 있고, 전체 문장을 해석할 때는 그것까지 포함해 의미를 파악해야 하는 것처럼, 서브쿼리도 전체 쿼리 안에서 독립된 의미를 가진다.
이 문제의 경우는 서브쿼리가 그룹별 최대값을 먼저 정의해 주고, 거기 있는 값들을 본 쿼리의 where 절이 넘겨받는 역할을 했다고 볼 수 있겠다.
코드카타를 진행하다 보면
다른 서브쿼리 활용 문제도 여러 번 마주하게 되겠지만,
나 혼자 문제를 해결할 때보다 다른 분들이 올려준 질문에 답해보는 과정에서 배우는 것이 훨씬 많다고 생각한다.
손으로만 알고 있던 걸 머리와 글로 정리하게 되는 효과도 있고.
앞으로도 내 공부 외에, 다른 분들이 올려주는 질문도
내 경험치다 생각하고 부지런히 고민하고 답해볼 생각이다.