Subquery
1. 서브쿼리 소개
- 조인을 통해 흩어진 테이블을 연결할 수 있습니다.
- 하지만 데이터에 질문을 던지다 보면,
JOIN만으로는 한 번에 답하기 어려운, 여러 단계의 사고를 거쳐야 하는 문제들을 만나게 됩니다.
1.1 문제 상황
"우리 쇼핑몰에서 판매하는 상품들의 평균 가격보다 비싼 상품은 무엇이 있을까?"
- 이 질문에 답하기 위해 대부분의 사람들은 자연스럽게 두 단계로 나누어 생각할 것입니다.
1단계: 전체 상품의 평균 가격을 구한다
SELECT AVG(price) FROM products;
실행 결과
| AVG(price) |
|---|
| 167166.6667 |
- 평균 가격이 약 167,167.67원이라는 것을 알 수 있습니다.
2단계: 그 평균 가격보다 비싼 상품을 찾는다
SELECT name, price
FROM products
WHERE price > 167166.67;
실행 결과
| name | price |
|---|---|
| 4K UHD 모니터 | 350000 |
| 스마트 워치 | 280000 |
1.2 두 번의 쿼리 실행의 문제점
번거롭다
- 매번 첫 번째 쿼리의 결과를 복사해서 두 번째 쿼리에 붙여 넣어야 합니다.
오류에 취약하다
- 만약 상품 데이터가 실시간으로 추가되거나 가격이 변경된다면 어떨까요?
- 1단계 쿼리를 실행하고 2단계 쿼리를 실행하는 그 짧은 순간에도 평균 가격은 변할 수 있습니다.
- 이렇게 되면 잘못된 기준으로 데이터를 조회하게 될 수도 있습니다.
해결책
- 이 두 단계를 논리적으로 완벽한 하나의 작업 단위로 묶고 싶습니다.
- 이럴 때 사용하는 기술이 바로 **서브쿼리(Subquery)**입니다.
1.3 서브쿼리의 개념
- 서브쿼리는 말 그대로 하나의 SQL 쿼리 문 안에 포함된 또 다른
SELECT쿼리를 의미합니다. - 바깥쪽의 메인쿼리가 실행되기 전에, 괄호
()안에 있는 서브쿼리가 먼저 실행됩니다. - 데이터베이스는 서브쿼리의 실행 결과를 바깥쪽 메인쿼리에게 전달하여, 메인쿼리가 그 결과를 사용해서 최종 작업을 수행하게 됩니다.
SELECT name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products);
쿼리 실행 순서
- 데이터베이스는 괄호 안의 서브쿼리
SELECT AVG(price) FROM products를 가장 먼저 실행합니다. - 서브쿼리가 실행된 결과인
167166.67이라는 단일 값을 얻습니다. - 이제 원래의 쿼리는 내부적으로 다음과 같이 변합니다:
SELECT name, price FROM products WHERE price > 167166.67; - 최종적으로 이 변환된 메인쿼리가 실행되어 결과를 보여줍니다.