SELECT SAL
FROM EMP
WHERE ENAME = 'JONES';
위의 결과를 보면 JONES의 급여는 2975이므로 이제 기준 급여 값을 알았으므로 이 급여보다 높은 급여를 받는 사원 데이터를 알 수 있다.
SELECT *
FROM EMP
WHERE SAL > 2975;
SELECT *
FROM EMP
WHERE SAL > (
SELECT SAL
FROM EMP
WHERE ENAME = 'JONES');
- 서브쿼리는 연산자와 같은 비교 또는 조회 대상의 오른쪽에 놓이며 괄호 ()로 묶어서 사용한다.
- 특수한 몇몇 경우를 제외한 대부분의 서브쿼리에서는 ORDER BY절을 사용할 수 없다.
- 서브쿼리의 SELECT절에 명시한 열은 메인쿼리의 비교 대상과 같은 자료형과 같은 개수로 지정해야 한다.
- 서브 쿼리에 있는 SELECT문의 결과 행 수는 함께 사용하는 메인쿼리의 연산자 종류와 호환 가능해야 한다.
> | >= | = | <= | < | <> | ^= | != |
---|
SELECT *
FROM EMP E
WHERE E.HIREDATE < (SELECT HIREDATE
FROM EMP
WHERE ENAME = 'SCOTT');
WHERE E.SAL > AVG(SAL)
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL, D.DEPTNO, D.LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.DEPTNO = 20
AND SAL > (SELECT AVG(SAL)
FROM EMP);
다중행 연산자 | 설명 |
---|---|
IN | 메인쿼리의 데이터가 서브쿼리의 결과 중 하나라도 일치한 데이터가 있다면 TRUE |
ANY, SOME | 메인쿼리의 조건식을 만족하는 서브쿼리의 결과가 하나 이상이면 TRUE |
ALL | 메인쿼리의 조건식을 서브쿼리의 결과 모두가 만족하면 TRUE |
EXISTS | 서브쿼리의 결과가 존재하면(즉, 행이 1개 이상일 경우) TRUE |
SELECT *
FROM EMP
WHERE DEPTNO IN(30, 20);
SELECT *
FROM EMP
WHERE SAL IN (
SELECT MAX(SAL)
FROM EMP
GROUP BY DEPTNO);
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);
대소 비교 연산자와 ANY연산자를 함께 사용하는 경우
SELECT *
FROM EMP
WHERE SAL < ANY(
SELECT SAL
FROM EMP
WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;
위의 결과를 보면, 서브쿼리 결과 값 중 최대값(SAL=2850)보다 작은 값은 모두 출력 대상이 된다.
따라서 < ANY 연산자는 서브쿼리에 MAX함수를 적용한 값을 ANY연산자 없이 비교 연산자(<)만 사용한 결과와 같은 효과를 낼 수 있다.
- 즉, < + ANY: 서브쿼리의 결과 값 중, 가장 큰 값보다 작으면 출력
/> + ANY: 서브쿼리의 결과 값 중, 가장 작은 값보다 작으면 출력
< + ANY 연산자를 사용한 경우 == < + MAX 함수를 사용한 경우
SELECT *
FROM EMP
WHERE SAL < (SELECT MAX(SAL)
FROM EMP
WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;
SELECT *
FROM EMP
WHERE SAL < (SELECT MAX(SAL)
FROM EMP
WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;
SELECT *
FROM EMP
WHERE
SAL < ALL(SELECT SAL
FROM EMP
WHERE DEPTNO= 30);
- 즉, < + ALL: 서브쿼리의 결과 값 중, 가장 작은 값보다 작으면 출력
/> + ALL: 서브쿼리의 결과 값 중, 가장 큰 값보다 작으면 출력
SELECT *
FROM EMP
WHERE
SAL > ALL(SELECT SAL
FROM EMP
WHERE DEPTNO= 30);
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 *
FROM EMP
WHERE (DEPTNO, SAL)
IN (SELECT DEPTNO, MAX(SAL) FROM EMP
GROUP BY DEPTNO);
SELECT *
FROM (SELECT * FROM EMP WHERE DEPTNO =10) E10,
(SELECT * FROM DEPT) D
WHERE E10.DEPTNO = D.DEPTNO;
WITH
[별칭1] AS (SELECT문 1),
[별칭2] AS (SELECT문 2),
...
[별칭N] AS (SELECT문 N),
SELECT
FROM 별칭1, 별칭2, 별칭3
...
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절에 명시하는 서브쿼리는 반드시 하나의 결과만 반환하도록 작성해 주어야 한다!
SELECT EMPNO, ENAME, JOB, SAL,
(SELECT GRADE
FROM SALGRADE
WHERE E.SAL BETWEEN LOSAL AND HISAL) AS SALGRADE,
DEPTNO,
(SELECT DNAME
FROM DEPT D
WHERE E.DEPTNO = D.DEPTNO) AS DNAME
FROM EMP E;
SELECT E.JOB, E.EMPNO, E.ENAME, E.SAL,
D.DEPTNO, D.DNAME
FROM EMP E, DEPT D
WHERE E.JOB = (SELECT JOB FROM EMP WHERE ENAME = 'ALLEN')
AND E.DEPTNO = D.DEPTNO;
SELECT E.EMPNO, E.ENAME, D.DNAME, E.HIREDATE, D.LOC, E.SAL,
(SELECT GRADE FROM SALGRADE S WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL) AS GRADE
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND SAL > (SELECT AVG(SAL) FROM EMP)
ORDER BY E.SAL DESC, E.EMPNO;
SELECT E.EMPNO, E.ENAME, E.JOB, D.DEPTNO, D.DNAME, D.LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.DEPTNO =10
AND E.JOB NOT IN(SELECT JOB FROM EMP WHERE DEPTNO=30);
SELECT E.EMPNO, E.ENAME, E.SAL, S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL
AND SAL > (SELECT MAX(SAL) FROM EMP WHERE JOB = 'SALESMAN')
ORDER BY E.EMPNO;
SELECT E.EMPNO, E.ENAME, E.SAL, S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL
AND SAL > ALL(SELECT SAL FROM EMP WHERE JOB = 'SALESMAN')
ORDER BY E.EMPNO;