서브쿼리 위치와 반환 형태
서브쿼리(Subquery)는 SQL 문장 안에 괄호로 넣은 또 다른 SELECT 문입니다. 바깥의 메인 쿼리가 필요로 하는 값·행 집합·조회 결과를 만들어 줍니다. 예를 들어 '전체 평균 시작가보다 비싼 물품'은 평균을 구하는 SELECT를 WHERE에 넣어 한 문장으로 조회합니다.
서브쿼리는 들어가는 위치에 따라 이름이 다릅니다. WHERE·HAVING에 넣으면 중첩 서브쿼리, SELECT 절에 넣으면 스칼라 서브쿼리, FROM 절에 넣으면 인라인 뷰입니다. 바깥 열을 참조하지 않는 서브쿼리는 메인 쿼리보다 먼저 실행될 수 있습니다.
반환 행 수로 단일행·다중행을, 반환 열 수로 단일컬럼·다중컬럼을 나눕니다. 단일행 서브쿼리는 =·>·< 같은 단일행 비교 연산자와, 다중행 서브쿼리는 IN·ANY(SOME)·ALL·EXISTS와 씁니다. 여러 행이 나오는 서브쿼리를 =로 비교하면 ORA-01427 오류가 납니다. 반대로 IN은 한 행만 나오는 서브쿼리에도 쓸 수 있습니다.
이 단원의 예시는 빈티지 물품 경매 데이터입니다. AUCTION에 물품 8건이 있고, 입찰 테이블 BID에는 101·103·202·203·302번 물품의 입찰이, 찜 목록 WATCHLIST에는 물품번호 102·201·NULL이 들어 있습니다.
| AUCTION_ | CATEGORY_ | TITLE | START_ |
|---|---|---|---|
| 101 | C1 | LP플레이어 | 80 |
| 102 | C1 | 카세트 | 120 |
| 103 | C1 | 턴테이블 | 220 |
| 201 | C2 | 필름카메라 | 140 |
| 202 | C2 | 폴라로이드 | 260 |
| 203 | C2 | 카메라렌즈 | 400 |
| 301 | C3 | 빈티지조명 | 60 |
| 302 | C3 | 스탠드 | 300 |
| 위치 | 이름 | 반환 | 기출 포인트 |
|---|---|---|---|
| WHERE · HAVING | 중첩 서브쿼리 | 단일행·다중행·다중컬럼 | 연산자와 반환 행 수가 맞아야 함 |
| SELECT | 스칼라 서브쿼리 | 1행 1열 | 0건 → NULL, 2건 이상 → 오류 |
| FROM | 인라인 뷰 | 테이블 형태 | 바깥에서는 인라인 뷰 별칭으로 참조 |
-- 단일행: 평균은 값 하나 → > 로 비교 (103, 202, 203, 302)
SELECT AUCTION_ID, START_PRICE
FROM AUCTION
WHERE START_PRICE >
(SELECT AVG(START_PRICE) FROM AUCTION);
-- 오류: C1 물품 3건이 나오는데 = 로 비교 → ORA-01427
SELECT AUCTION_ID
FROM AUCTION
WHERE START_PRICE =
(SELECT START_PRICE FROM AUCTION
WHERE CATEGORY_CODE = 'C1');
-- 정상: 여러 행은 IN으로 (101, 102, 103)
SELECT AUCTION_ID
FROM AUCTION
WHERE START_PRICE IN
(SELECT START_PRICE FROM AUCTION
WHERE CATEGORY_CODE = 'C1');