단일행과 다중행 서브쿼리
서브쿼리를 쓸 수 있는 절과 이름, 하나의 값을 돌려주는 단일행 서브쿼리와 여러 값을 돌려주는 다중행 서브쿼리, 각각에 쓰는 비교 연산자
#핵심 요약
서브쿼리는 GROUP BY 절만 빼고 SELECT 문의 모든 절에 쓸 수 있음
서브쿼리가 메인쿼리로 한 행의 값을 돌려주면 단일행 서브쿼리이고 =, !=, <>, ^=, >, <, >=, <=를 씀
여러 행의 값을 돌려주면 다중행 서브쿼리이고 IN, NOT IN, >ALL, <ALL, >ANY, <ANY를 씀
IN은 =ANY, NOT IN은 !=ALL과 같음
#개념과 동작 원리
서브쿼리 위치와 이름:
| 절 | 서브쿼리 이름 |
|---|---|
SELECT |
스칼라 서브쿼리 |
FROM |
인라인 뷰 |
WHERE |
서브쿼리 |
GROUP BY |
쓸 수 없음 |
HAVING |
서브쿼리 |
ORDER BY |
스칼라 서브쿼리 |
FROM 절의 서브쿼리를 인라인 뷰, WHERE 절의 서브쿼리를 중첩 서브쿼리(nested subquery)라고도 함
IN은 "목록의 어느 하나와 같다"는 검사로 =ANY와 같음NOT IN은 !=ALL과 같음
#필수 명령어 또는 SQL
#단일행 서브쿼리
SELECT ename, sal
FROM emp
WHERE sal = (SELECT sal FROM emp WHERE ename = 'SCOTT')
AND ename != 'SCOTT';
SELECT ename, sal
FROM emp
WHERE sal = (SELECT MAX(sal) FROM emp);결과 해석:
실습에서는 두 번째 문장(최대 월급 사원)을 "튜닝 전"으로, ORDER BY sal DESC FETCH FIRST 1 ROWS ONLY를 "튜닝 후"로 두고 DBMS_XPLAN.DISPLAY_CURSOR로 버퍼 수를 비교했음
최대 월급이 같은 사원이 둘 이상이면 두 문장의 결과 행 수가 달라질 수 있음(FETCH FIRST 1 ROWS ONLY는 한 행만 돌려줌)
#다중행 서브쿼리
SELECT ename, sal
FROM emp
WHERE sal IN (SELECT sal FROM emp WHERE job = 'SALESMAN');결과 해석:
설명: 서브쿼리가 여러 값을 돌려줄 때는 다중행 연산자를 써야 함
위 문장에서 IN 대신 =를 쓰면 서브쿼리가 여러 행을 돌려주므로 오류가 남(오류 번호 확인 불가)
연습 문제(답 확인 불가): 월급이 1000~3000인 사원들과 직업이 같은(또는 같지 않은) 사원 찾기job IN (SELECT job FROM emp WHERE sal BETWEEN 1000 AND 3000) 형태가 됨
"같지 않은" 쪽은 NOT IN의 NULL 주의점이 있음(NOT IN과 NULL)