JOIN, SUB QUERY
1. 서브쿼리
1) 서브쿼리 사용 가능한 장소
- SELECT 절
- FROM 절
- WHERE 절
- HAVING 절
- ORDER BY 절
- INSERT VALUES 절
- UPDATE SET 절
2) 유형
- 단일행: SELECT문에서 하나의 행만 찾기
- 한 행에 대한 결과값만 반환
- 등호, 부등호 이용 (=, <, > ...)
예) SELECT ename 이름, dno 사번
FROM emp
WHERE dno = (SELECT dno FROM emp WHERE eno = 20);
=> 20번 사원과 같은 부서에서 일하는 사원 찾기
- 다중행: SELECT 문에서 하나 이상의 행 찾기
- 여러 행에 대한 값 반환
- 다중행 서브쿼리때 단일행 서브쿼리에서 사용하는 등호나 부등호 사용시 에러
- IN, NOT IN, ALL, ANY, EXISTS
-- IN: 서브쿼리 결과에 존재하는 임의의 값과 동일한 조건
-- ALL: 서브쿼리에 존재하는 모든 값을 만족하는 조건 의미
-- ANY: 서브쿼리 내에 존재하는 값 중 어느 하나라도 만족하면 출력
-- EXISTS: 서브쿼리의 결과를 만족하는 값이 존재하는지 여부 판단, 조건을 만족하는 건이 1건을 찾으면 더이상 찾지 않음
예) SELECT ename 이름, sal 급여
FROM emp
WHERE deptno != 20
AND sal > ANY(SELECT sal FROM emp WHERE job = 'SALESMAN');
=> SALESMAN 중 한 명보다 급여를 많이 받는 사원명과 급여
SELECT ename 이름, sal 급여
FROM emp
WHERE deptno != 20
AND sal > ALL(SELECT sal FROM emp WHERE job='SALESMAN');
=> 모든 SALESMAN보다 급여를 많이 받는 사원명과 급여
- 다중열(다중컬럼): SELECT 문장 하나 이상의 컬럼을 검색하는 질의
- 서브쿼리에서 여러 열(컬럼)에 대한 결과 값을 반환
- 서브쿼리와 메인쿼리에서 비교하고자 하는 컬럼 개수와 위치가 동일해야 함
- 서브쿼리의 결과로 여러 개의 컬럼이 반환되어 메인쿼리와 동시에 비교되는 것
예) SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, HEIGHT 키
FROM PLAYER
WHERE (TEAM_ID, HEIGHT) IN (SELECT TEAM_ID, MIN(HEIGHT)
FROM PLAYER
GROUP BY TEAM_ID)
ORDER BY TEAM_ID, PLAYER_NAME;
=> 선수 테이블에서 키가 가장 작은 선수의 팀코드와 키를 잡아내서 팀코드와 선수이름으로 정렬
- FROM절 상의 서브쿼리: inline view
- VIEW처럼 작용
예) SELECT e.ename, e.salary, a.avg_sal
FROM employee e, (SELECT dno, AVG(salary) avg_sal
FROM employee GROUP BY dno) a
WHERE e.dno = a.dno;
=> 사원 정보와 각 사원이 속한 부서의 평균 급여를 함께 출력
2. JOIN
- 2개 이상의 테이블을 연결하여 데이터를 검색하는 법
1-1) EQUI JOIN
- 두 테이블 간 값이 일치하는 경우
- JOIN 조건으로 '=' 연산자 이용
예) SELECT e.eno 사번, e.ename 사원명, d.dno 부서번호, d.dname 부서명
FROM employee e, department d
WHERE e.dno = d.dno;
=> 사원이 어떤 부서에 근무하는지 출력
1-2) NON EQUI JOIN
- 두 테이블 간 값이 일치하지 않는 경우
- 범위 연산자 사용 (BETWEEN ~ AND ~)
예) SELECT e.ename 사원명, e.salary 급여, s.grade 등급
FROM employee e, salary s
WHERE e.salary BETWEEN s.low_sal AND s.high_sal
=> 사원이 받는 급여 등급 조회
2-1) inner JOIN
- 교집합
- 두 테이블 간의 조인 조건을 만족하는 row만 출력
예) SELECT e.eno 사번, e.ename 사원명, d.dno 부서번호, d.dname 부서명
FROM employee e INNER JOIN department d
ON e.dno = d.dno;
=> 사원이 어떤 부서에 근무하는지 출력(EQUI JOIN과 동일한 결과)
2-2) outer JOIN
- JOIN 조건에서 한쪽 값이 없어도 row 반환(출력)
- 동일 조건에서 조인 조건을 만족하는 값이 없는 행을 조회하기 위해 사용
- (+) 연산자 사용
- ANSI 표준인 LEFT / RIGHT / FULL JOIN도 사용 가능
-- LEFR OUTER JOIN: JOIN 수행 시 왼쪽 테이블 데이터를 기준으로 JOIN 수행
-- RIGHT OUTER JOIN: JOIN 수행 시 오른쪽 테이블 데이터를 기준으로 JOIN 수행
-- FULL OUTER JOIN: JOIN 수행 시 왼, 오른 모든 테이블의 데이터를 읽어 JOIN 수행
예) SELECT e.eno 사번, e.ename 사원명, d.dno 부서번호, d.dname 부서명
FROM employee e LEFT OUTER JOIN department d
ON e.dno = d.dno;
=> 사원이 어떤 부서에 근무하는지 검색, 부서를 아직 배정받지 못한 사원도 검색
예) SELECT e.eno 사번, e.ename 사원명, d.dno 부서번호, d.dname 부서명
FROM department d RIGHT OUTER JOIN employee e
ON e.dno = d.dno;
=> 사원이 어떤 부서에 근무하는지 검색, 부서를 아직 배정받지 못한 사원 및 사원이 없는 부서도 검색