SQL문 속 또 다른 SQL문, 서브 쿼리
- SQL문 내부에 사용하는 SELECT문을 의미
SELECT 서브쿼리(1)FROM 서브쿼리(2)WHERE 서브쿼리(3)
(1) 스칼라 서브쿼리
(2) 인라인 뷰: 가상의 테이블
(3) 상관 부속 질의
SELECT 조회할 열
FROM 조회할 테이블
WHERE 조건식 ( SELECT 조회할 열 FROM 조회할 테이블 WHERE 조건식 )
-- 서브쿼리로 JONES의 급여보다 높은 급여를 받는 사원 정보 출력
SELECT * FROM EMP
WHERE SAL > (SELECT SAL FROM EMP WHERE ENAME = 'JONES');
1) 서브 쿼리는 연산자와 같은 비교 또는 조회 대상의 오른쪽에 놓이며 괄호( )로 묶어서 사용합니다.
2) 특수한 몇몇 경우를 제외한 대부분의 서브쿼리에서는ORDER BY 절을 사용할 수 없습니다.
3) 서브쿼리의 SELECT절에 명시한 열은 메인쿼리의 비교 대상과 같은 자료형과 같은 개수로 지정해야 합니다. 즉 메인쿼리의 비교 대상 데이터가 하나라면 서브쿼리의 SELECT절 역시 같은 자료형인 열을 하나 지정해야 합니다.
4) 서브쿼리에 있는 SELECT문의 결과 행 수는 함께 사용하는 메인쿼리의 연산자 종류와 호환 가능해야 합니다.
예를 들어 메인쿼리에 사용한 연산자가 단 하나의 데이터로만 연산이 가능한 연산자라면 서브쿼리의 결과 행 수는 반드시 하나여야 합니다.
단일행 서브 쿼리(single-row subquery)는 실행 결과가 단 하나의 행으로 나오는 서브쿼리를 뜻합니다.
서브쿼리에서 출력되는 결과가 하나이므로 메인쿼리와 서브쿼리 결과는 다음과 같이 단일행 연산자를 사용하여 비교
ex) 30번 부서의 최소 급여보다 적게 받는 직원 목록


🔽


SELECT * FROM EMP
WHERE HIREDATE < (SELECT HIREDATE FROM EMP WHERE ENAME = 'SCOTT');
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL, D.DEPTNO, D.DNAME, D.LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.DEPTNO = 20
AND E.SAL > (SELECT AVG(SAL) FROM EMP);
다중행 서브쿼리(multiple-row subquery)는 실행 결과 행이 여러 개로 나오는 서브쿼리를 가리킵니다.
단일행 서브쿼리와 달리 서브쿼리 결과가 여러 개이므로 단일행 연산자는 사용할 수 없고 다중행 연산자를 사용해야 메인쿼리와 비교할 수 있습니다.


-- 부서별 최대 급여 직원 목록
SELECT * FROM EMP
WHERE SAL IN (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
-- 부서별 최대 급여가 아닌 직원 목록
SELECT * FROM EMP
WHERE SAL NOT IN (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
#ANY
-- 부서별 최대 급여 직원 목록
SELECT * FROM EMP
WHERE SAL = ANY(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
-- SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO 여기서 나온 결과중 어떤값 중 하나라도 SAL과 같으면 참
ex) 30번 부서의 최대 급여보다 적게 받는 직원 목록

ex) 30번 부서의 최소 급여보다 더 많이 받는 직원 목록

ex) 30번 부서의 최대 급여보다 더 많이 받는 직원

ex) 30번 부서의 최대 급여보다 많이 받는 직원 목록

SELECT SAL FROM EMP WHERE DEPTNO=30 ORDER BY DEPTNO DESC;
--결과
SAL > 2850
SAL > 1600
SAL > 1500
SAL > 1250
SAL > 950
이 모두 참이여야 참이므로 가장 큰 값 2850보다 커야 참이된다.
ex) 30번 부서가 부서 테이블에 존재하면 직원목록 출력

참이 아닐경우🔽

서브쿼리의 SELECT절에 비교할 데이터를 여러 개 지정하는 방식
다중열 서브쿼리 사용하기



✔인라인 뷰의 단점: FROM절의 쿼리가 너무 길어진다.
WITH
E AS (SELECT EMPNO, ENAME, JOB, SAL, DEPTNO
FROM EMP WHERE DEPTNO IN (10,20)),
D AS (SELECT * FROM DEPT)
SELECT E.EMPNO, E.ENAME, D.DNAME
FROM E,D
WHERE E.DEPTNO = D.DEPTNO AND E.SAL >= 2000;

스칼라 서브쿼리(scalar subquery)
스칼라: 단일값 - 단일행 서브쿼리
SLECT절에 서브쿼리 사용하기
SELECT EMPNO, ENAME,
(SELECT DNAME FROM DEPT D WHERE D.DEPTNO = E.DEPTNO) DNAME
FROM EMP E;
-- 각 레코드마다 각각 실행되기 때문에 좋은코드가 아니다 성능 xx

-> 2개 이상의 행이 리턴됨 오류