하나의 sql 명령문의 결과를 다른 sql명령문에 전달하기 위해 두개 이상의 sql명령문을 하나의 sql명령문으로 연결하여 처리하는 방법을 말한다.
1) 사원 정보에서 급여의 최고 정보를 가져올 때
1) 서버 쿼리는 메인쿼리가 실행되기 전에 한번씩 실행되고,
2) 서브 쿼리에서 실행된 결과가 메인 쿼리에 전달되어 최종적인 결과를 출력 처리.
-- 급여가 최고인 사원의 정보(사원 모든 컬럼)를 출력하세요
-- 1) 최고 급여
-- 2) 그 급여와 동일한 급여를 조회
SELECT *
FROM emp
WHERE sal = (
SELECT max(sal)
FROM emp
);
--ex1) 급여가 최저인 사원의 정보를 출력하세요
SELECT *
FROM emp
WHERE sal = (
SELECT min(sal)
FROM emp
);
--ex2) 최근에 입사한 사원의 정보를 출력하세요.
SELECT *
FROM emp
WHERE hiredate = (
SELECT max(hiredate)
FROM emp
);
subquery를 통해 결과가 행이 1개인 경우와 여러개인 경우로 나누어서 사용할 수 있다.
1) 서브쿼리에서 단 하나의 행만을 검색하여 메인쿼리에 반환하는 질의문
2) 메인쿼리의 where 절에서 서브쿼리의 결과와 비교할 경우에는 반드시 단일행 비교 연산자
중 하나만 사용해야 함
-- 방법1
-- 부서명이 SALES인 부서번호를 검색
-- 그 부서정보와 동일한 사원들 검색
SELECT *
FROM EMP e
WHERE DEPTNO = (
SELECT DEPTNO
FROM DEPT
WHERE DNAME = 'SALES'
);
-- 방법2
-- 부서번호 중에 가장 낮은 정보를 검색
-- 그 부서번호에 해당하는 사원들 검색
SELECT *
FROM EMP e
WHERE DEPTNO = (
SELECT MIN(DEPTNO)
FROM DEPT);
-- 평균 급여보다 높은 사원 정보를 출력
-- 1) 평균 급여
SELECT AVG(SAL) 평균급여
FROM EMP;
-- 2) 평균급여 초과 정보 검색
SELECT *
FROM EMP e
WHERE sal > (
SELECT AVG(SAL) 평균급여
FROM EMP
);
-- 3) 평균급여 미만 정보 검색
-- 테이블을 모든 row를 일단 처리해야지 그룹함수의 데이터가 나오기에 먼저 subquery로
처리하고 그 다음 메인 쿼리에서 데이터를 처리한다.
SELECT *
FROM EMP e
WHERE sal < (
SELECT AVG(SAL) 평균급여
FROM EMP
);
-- ex1) 30번 부서에 최고 급여자 보다 높은 사원을 검색하세요.
SELECT *
FROM EMP e
WHERE sal > (
SELECT max(sal)
FROM EMP
where deptno=30
);
-- ex2) 직책이 CLERK 사람의 평균 급여보다 낮은 사원을 검색하세요
SELECT *
FROM EMP e
WHERE sal < (
SELECT AVG(SAL)
FROM EMP
WHERE job = 'CLERK'
);
-- ex3) 관리자가 'MANAGER'인 사원의 최저 급여보다 적은 사원들 출력하세요.
SELECT *
FROM EMP e
WHERE sal < (
SELECT sal
FROM EMP e
WHERE sal = (
SELECT min(sal)
FROM EMP e
WHERE job='MANAGER'
));
--ex4) emp, salgrade테이블과 조인하여, 등급이 1~2등급인 사원의 최고 급여보다 많은 사원을
출력하세요.
SELECT *
FROM emp
WHERE sal > (
SELECT max(sal)
FROM EMP, SALGRADE
WHERE empno BETWEEN losal AND hisal
);
-- ANY,SOME()
-- any는 어느 하나라도 충족하면 된다. or 조건으로 연결
SELECT *
FROM EMP e
WHERE sal > any(
SELECT SAL
FROM EMP
WHERE DEPTNO =20
);
SELECT *
FROM EMP e
WHERE sal > (
SELECT min(SAL)
FROM EMP
WHERE deptno = 20);
------------------------ALL() -- all은 나오는 데이터가 and
SELECT *
FROM EMP e
WHERE sal > (
SELECT max(SAL)
FROM EMP
WHERE deptno = 20);
-- 관리자 번호가 null인 것이 존재할 때, 사원 정보를 조회하라
SELECT *
FROM emp
WHERE EXISTS (
SELECT mgr
FROM EMP e
WHERE mgr IS NULL);
-- ex1) 부서번호가 40번이 없을 때, 부서번호가 10인 사원 정보를 출력
-- hint) exist(), not exist(), where에 위 내용 다음 and도 가능
--1단계)
SELECT *
FROM emp
WHERE NOT EXISTS (
SELECT deptno
FROM emp
WHERE deptno=40
);
--2단계)
SELECT *
FROM emp
WHERE NOT EXISTS (
SELECT deptno
FROM emp
WHERE deptno=40)
AND deptno = 10;
-- ex2) 보너스가 0인 데이터가 있을 떄, 보너스가 null이 아닌 사원 정보를 출력
--1단계)
SELECT comm
FROM EMP e
WHERE comm = 0
--2단계)
SELECT *
FROM emp
WHERE EXISTS (
SELECT comm
FROM EMP e
WHERE comm = 0)
AND comm IS NOT NULL;
-- null에 대한 검색 조건 컬럼명=null(X) -- 컬럼명 is null : 해당 데이터가 없을 때
-- 컬럼명 is not null : 해당 데이터가 있을 때
SELECT *
FROM (
SELECT empno, ename, job
FROM EMP
WHERE deptno = 10
);
SELECT d.*, sal
FROM (
SELECT deptno, max(sal) sal
FROM EMP e
GROUP BY deptno
)e, dept d
WHERE e.deptno = d.deptno
-- ex) 인라인뷰1 (직책별 최고 급여), 사원 전체(emp)
-- 조인 : 급여
-- ==> 직책별 최고 급여자의 정보를 출력
-- 1단계
SELECT job, max(sal) sal
FROM EMP e
GROUP BY job;
-- 2단계
SELECT me.*, e.*
FROM (
SELECT job, max(sal) sal
FROM EMP e
GROUP BY job) me, emp e
WHERE me.sal = e.sal
ORDER BY me.sal;
-- 과제 1. inline view을 활용하여 분기별 최저급여자의 사원 정보를 출력하세요.
SELECT me.*, e.*
FROM (
SELECT to_char(hiredate,'Q') 분기, min(sal) sal
FROM EMP e
GROUP BY to_char(hiredate,'Q')) me, emp e
WHERE me.sal = e.sal
ORDER BY me.sal;