Sub Query는 쿼리 안의 쿼리라고 이해하면 쉬울수도 있다.
일반적으로 Select ~ From ~;과 같이 쓰는데
서브 쿼리는 Select ~ From (Select ~ From ~);
위와 같이 쿼리 안에 쿼리는 넣는다
특정 테이블에서 뽑은 데이터를
다시한번 검색하는것이다.
보통 테이블을 2개 이상 사용할 때나 key값이 연관이 있을 때 사용한다.
예를 보면 좀 더 쉽게 이해될것이다.
-- 테이스를 위한 테이블 생성 -- 직원 테이블 생성 CREATE TABLE emp( ename VARCHAR2(20), job VARCHAR2(50), deptno VARCHAR2(10), hiredate DATE ); -- 부서 테이블 생성 CREATE TABLE dept( deptno VARCHAR2(10), deptname VARCHAR2(20), loc VARCHAR2(10) ); -- 테스트를 위한 데이터 삽입 INSERT INTO emp VALUES('lee', 'staff', 1, to_date('15/01/02', 'YY/MM/DD')); INSERT INTO emp VALUES('kim', 'staff', 1, to_date('15/03/06', 'YY/MM/DD')); INSERT INTO emp VALUES('jun', 'assistant', 2, to_date('15/05/15', 'YY/MM/DD')); INSERT INTO emp VALUES('chu', 'staff', 1, to_date('15/07/08', 'YY/MM/DD')); INSERT INTO emp VALUES('sin', 'manager', 2, to_date('15/10/28', 'YY/MM/DD')); INSERT INTO emp VALUES('jin', 'assistant', 1, to_date('15/12/25', 'YY/MM/DD')); INSERT INTO emp VALUES('son', 'staff', 2, to_date('16/01/13', 'YY/MM/DD')); INSERT INTO emp VALUES('han', 'staff', 3, to_date('16/04/06', 'YY/MM/DD')); INSERT INTO emp VALUES('hyun', 'leader', 4, to_date('16/08/15', 'YY/MM/DD')); INSERT INTO emp VALUES('ma', 'manager', 4, to_date('16/11/11', 'YY/MM/DD')); INSERT INTO dept VALUES(1, 'sales', 'NEWYORK'); INSERT INTO dept VALUES(2, 'dev01', 'LA'); INSERT INTO dept VALUES(3, 'personal', 'NEWYORK'); INSERT INTO dept VALUES(4, 'delevery', 'BOSTON'); SELECT * FROM emp; SELECT * FROM dept; -- deptno가 pk, fk가 된다. -- 문제 1) han의 근무 부서를 찾아라 -- 1단계 - 결과 3 SELECT deptno FROM emp WHERE ename = 'han'; -- 2단계 - 결과 찾기 SELECT deptname FROM dept WHERE deptno = 3; -- 3단계 - 합치기 SELECT deptname FROM dept WHERE (SELECT deptno FROM emp WHERE ename = 'han') = deptno; -- 문제 2) 위치가 LA나 BOSTON인 부서에 속한 사람들의 이름과 직책 -- 1단계(in이 마음에 안들면 or을 쓰자 SELECT deptno FROM dept WHERE loc IN('LA', 'BOSTON'); -- 2단계 SELECT ename, job FROM emp WHERE deptno IN(2,4); -- 3단계 SELECT ename, job FROM emp WHERE deptno IN(SELECT deptno FROM dept WHERE loc IN('LA', 'BOSTON')); -- 비교 연산자 -- IN : 메인 쿼리와 비교 조건이 서브 쿼리의 결과 중 하나라도 일치하면, OR와 비슷 (비교만 가능) -- ALL : 메인 쿼리와 비교 조건이 서브 쿼리의 결과 중 모두 일치하면, AND와 비슷 -- EXISTS : 메인 쿼리와 비교 조건이 서브 쿼리의 결과 중 값이 하나라도 있으면, OR와 비슷 (작다, 크다 등 가능) -- 문제 3) 직책이 MANAGER인 사원들 중 가장 입사일이 빠른 사원보다 입사일이 빠른 직원의 데이터 -- 1단계 SELECT MIN(hiredate) FROM emp WHERE job = 'manager'; -- 2단계 SELECT ename, job FROM emp WHERE hiredate < '15/10/28'; -- 3단계 SELECT ename, job FROM emp WHERE hiredate < (SELECT MIN(hiredate) FROM emp WHERE job = 'manager'); -- 문제 4) sales 부서에서 일하는 사원 정보 추출(이름, 직책, 입사일) -- 1단계 SELECT deptno FROM dept WHERE deptname = 'sales'; -- 2단계 SELECT ename, job, hiredate FROM emp WHERE deptno = 1; -- 3단계 SELECT ename, job, hiredate FROM emp WHERE deptno = (SELECT deptno FROM dept WHERE deptname = 'sales'); -- 문제 5) 부서별로 직원이 몇명인지 확인 -- 추출한 값을 하나의 컬럼처럼 보여주는 것 -> 상하관계 쿼리 SELECT deptname, loc, (SELECT COUNT(*) FROM emp WHERE emp.deptno = dept.deptno) AS cnt FROM dept; -- dept d, dept AS d 와 같이 식별자를 지정하여 사용할 수 있음 SELECT deptname, loc, (SELECT COUNT(*) FROM emp WHERE emp.deptno = d.deptno) AS cnt FROM dept d;