
SELECT SAL
FROM EMP
WHERE ENAME = 'JONES';
| SAL |
|---|
| 2975 |
SELECT *
FROM EMP
WHERE SAL > 2975;

SELECT *
FROM EMP
WHERE SAL > (SELECT SAL
FROM EMP
WHERE ENAME = 'JONES');

- 서브쿼리는 연산자와 같은 비교 또는 조회 대상의 오른쪽에 놓이며 괄호 ()로 묶어서 사용
- 특수한 경우를 제외한 대부분의 서브쿼리에서는 ORDER BY절을 사용할 수 없음
- 서브쿼리의 SELECT절에 명시한 열은 메인쿼리의 비교 대상과 같은 자료형과 같은 개수로 지정해야 함
- 즉 메인쿼리의 비교 대상 데이터가 하나라면 서브쿼리의 SELECT절 역시 같은 자료형인 열을 하나 지정해야 함
- 서브쿼리에 있는 SELECT문의 결과 행 수는 함께 사용하는 메인쿼리의 연산자 종류와 호환 가능해야 함
- 예를 들어 메인쿼리에 사용한 연산자가 단 하나의 데이터로만 연산이 가능한 연산자라면 서브쿼리의 결과 행 수는 반드시 하나여야 함
서브쿼리에서 출력되는 결과가 하나이므로 메인쿼리와 서브쿼리 결과는 다음과 같이 단일행 연산자를 사용하여 비교
> | >= | = | <= | < | <> | ^= | != |
|---|---|---|---|---|---|---|---|
| 초과 | 이상 | 같음 | 이하 | 미만 | 같지 않음 | 같지 않음 | 같지 않음 |
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);

실행 결과 행이 여러 개로 나오는 서브쿼리. 다중행 연산자를 사용함.
IN : 메인쿼리의 데이터가 서브쿼리의 결과 중 하나라도 일치한 데이터가 있다면 trueANY, SOME : 메인쿼리의 조건식을 만족하는 서브쿼리의 결과가 하나 이상이면 trueALL : 메인쿼리의 조건식을 서브쿼리의 결과 모두가 만족하면 trueEXISTS : 서브쿼리의 결과가 존재하면(즉, 행이 1개 이상일 경우) trueSELECT *
FROM EMP
WHERE SAL IN (SELECT MAX(SAL)
FROM EMP
GROUP BY DEPTNO);

SELECT *
FROM EMP
WHERE SAL = ANY (SELECT MAX(SAL)
FROM EMP
GROUP BY DEPTNO);
SELECT *
FROM EMP
WHERE SAL = SOME (SELECT MAX(SAL)
FROM EMP
GROUP BY DEPTNO);

SELECT *
FROM EMP
WHERE SAL < ANY(SELECT SAL
FROM EMP
WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;

< ANY 연산자는 서브쿼리 결과 값 중 최댓값보다 작은 값은 모두 출력 대상| < ANY 연산자를 사용한 경우 | 서브쿼리에 MAX 함수를 사용한 경우 |
|---|---|
|
|
SELECT *
FROM EMP
WHERE SAL > ANY(SELECT SAL
FROM EMP
WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;

> ANY 연산자는 서브쿼리 결과 값 중 최솟값보다 큰 값은 모두 출력 대상서브쿼리의 모든 결과가 조건식에 맞아떨어져야만 메인쿼리의 조건식이 true가 되는 연산자
1. 부서 번호가 30번인 사원들의 최소 급여보다 더 적은 급여를 받는 사원 출력하기
SELECT *
FROM EMP
WHERE SAL < ALL (SELECT SAL
FROM EMP
WHERE DEPTNO = 30);

SELECT *
FROM EMP
WHERE SAL > ALL (SELECT SAL
FROM EMP
WHERE DEPTNO = 30);

서브쿼리에 결과 값이 하나 이상 존재하면 조건식이 모두 true, 존재하지 않으면 false가 되는 연산자
1. 서브쿼리에 결과 값이 존재하는 경우
SELECT *
FROM EMP
WHERE EXISTS (SELECT DNAME
FROM DEPT
WHERE DEPTNO = 10);

SELECT *
FROM EMP
WHERE EXISTS (SELECT DNAME
FROM DEPT
WHERE DEPTNO = 50);
결과: 선택된 레코드가 없습니다.
서브쿼리의 SELECT절에 비교할 데이터를 여러 개 지정하는 방식
SELECT *
FROM EMP
WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL)
FROM EMP
GROUP BY DEPTNO);

SELECT E10.EMPNO, E10.ENAME, E10.DEPTNO, D.DNAME, D.LOC
FROM (SELECT * FROM EMP WHERE DEPTNO = 10) E10,
(SELECT * FROM DEPT) D
WHERE E10.DEPTNO = D.DEPTNO;
WITH -- 별칭 지정
E10 AS (SELECT * FROM EMP WHERE DEPTNO = 10),
D AS (SELECT * FROM DEPT)
SELECT E10.EMPNO, E10.ENAME, E10.DEPTNO, D.DNAME, D.LOC
FROM E10, D
WHERE E10.DEPTNO = D.DEPTNO;

SELECT *
FROM EMP E1
WHERE SAL > (SELECT MIN(SAL)
FROM EMP E2
WHERE E2.DEPTNO = E1.DEPTNO)
ORDER BY DEPTNO, SAL;
SELECT EMPNO, ENAME, JOB, SAL,
(SELECT GRADE
FROM SALGRADE
WHERE E.SAL BETWEEN LOSAL AND HISAL) AS SALGRADE,
DEPTNO,
(SELECT DNAME
FROM DEPT
WHERE E.DEPTNO = DEPT.DEPTNO) AS DNAME
FROM EMP E;
