2. JOIN
. 한 개 이상의 테이블로부터 데이터를 조회하는 것
. 주로 Primary-Key 와 Foreign-Key 의 관계를 가진
컬럼을
소유하고 있는 테이블을 통한 검색 시 사용
부서번호 부서명 지역코드사원번호 사원명 직급 급여 부서번호
1 주종면 차장 300 10
2 주영현 과장 250 10
3 홍경옥 과장 200 20
10 전산과 1
20 경영지원과 1
EMP DEPT
SELECT E. 사원번호 , E. 사원명 , D. 부서명
FROM EMP E, DEPT D
WHERE E. 부서번호 = D. 부서번호 ;
1 주종면 전산과
2 주영현 전산과
3 홍경옥 경영지원과2
3. JOIN 문법 -SQL1999(9i)
SELECT table1.column, table2.column
FROM table1
[ CROSS JOIN table2 ]
[ NATURAL JOIN table2 ]
[ JOIN table2 USING (column_name) ]
[ JOIN table2 ON (table1.column = table2.column) ]
[ LEFT FULL OUTER JOIN table2 ON (table1.column = table2.column) ]
[ RIGHT FULL OUTER JOIN table2 ON (table1.column = table2.column) ] ;
1
2
3
4
3
4. JOIN 의 종류
(9i) 형 식구 분
Master & Detail 의 관계를 가진 2 개 이상의 테이블에서
공통되는 칼럼을 서로 동등 비교 (=) 하여 조인하는 방법
(ex)
SELECT E. 사원번호 , E. 사원명 , D. 부서명
FROM EMP E, DEPT D
WHERE E. 부서번호 = D. 부서번호 ;
Natural Join
. 하나의 테이블에 있는 어떠한 칼럼도 조인할 테이블의
어떤 칼럼에 직접적으로 일치하지 않을 때 사용
. 조인조건은 equal(=) 이외의 연산자를 포함한다 .
(ex)
SELECT E. 사원번호 , E. 사원명 , D. 부서명
FROM EMP E, DEPT D
WHERE E. 급여 BETWEEN 100 AND 300;
CROSS Join
4
5. 형 식구 분
. 행이 조인 조건을 만족하지 않을때는 해당 행은 query
결과에 나타나지 않는다 .
. 조인 조건을 사용할 때 조인 조건을 만족하지 않는 행들
도 결과에 나타내고자 하는 경우 사용
. 조인 시킬 값이 없는 조인측에 (+) 를 위치 시킨다 .
(ex)
SELECT E. 사원번호 , E. 사원명 , D. 부서명
FROM EMP E, DEPT D
WHERE E. 부서번호 (+) = D. 부서번호 ;
FULL 또는 Two-Way
OUTER Join
. 한 개 테이블을 두개의 별도의 테이블처럼 사용할 때
사용
. 한 개 테이블의 행들을 같은 테이블의 행들과 조인한다 .
(ex)
SELECT E. 사원번호 , E. 사원명 , M. 사원명
FROM EMP E, EMP D
WHERE E. 사원번호 = M. 부서장번호 ;
USING 절 Join
5
6. SubQuery
. Query 문장에 사용된 또 다른 Query 문장을 의미
SELECT ……
FROM …….
WHERE (……..
);
- SELECT 절
- WHERE 절
(SELECT/UPDATE/DELETE )
- HAVING 절
- UPDATE 문장의 SET 절
- INSERT 문장의 INTO 절
(SELECT …….
FROM …….
WHERE …….);
SUB-QUERY
(Inner Query)
MAIN-QUERY
(Outer Query)
6
7. SubQuery 의 종류
형 식구 분
SELECT *
FROM EMP
WHERE JOB = (SELECT JOB
FROM EMP
WHERE ENAME = 'FORD');
단일행 Subquery
(=,<,>,<=,>=,<>)
SELECT *
FROM EMP
WHERE JOB IN (SELECT JOB
FROM EMP
WHERE ENAME = 'FORD‘
OR ENAME = ‘JAMES' );
복수행 Subquery
(IN, ANY, ALL)
7
8. 복수 행 연산
자종 류 예 제
EXISTS
SUB-QUERY 의 결과를 만족하는 값이 존재하는지 여부를 확인하는 경우
SELECT dname, deptno FROM dept WHERE EXISTS
(SELECT * FROM EMP WHERE emp.deptno = 10);
IN
SUB-QUERY 에 의한 결과가 여러 행인 경우
SELECT * FROM emp
WHERE job IN (SELECT job FROM emp WHERE deptno =30);
ANY, SOME
SUB-QUERY 에 의한 결과 값 중에서 하나 이상을 만족하는 행이 있는 경우
SELECT * FROM emp
WHERE sal < ANY (SELECT sal FROM emp WHERE deptno =30);
ALL
SUB-QUERY 에 의한 결과 값 모두를 만족하는 행이 있는 경우
SELECT * FROM emp WHERE sal = ALL (3000);
8
9. 형 식구 분
SELECT *
FROM EMP
WHERE (SAL, DEPTNO) IN
(SELECT MIN(SAL), DEPTNO
FROM EMP
GROUP BY DEPTNO);
복수컬럼 Query
SELECT E.EMPNO, E.ENAME, E.DEPTNO
FROM EMP E
WHERE SAL > (SELECT AVG(SAL)
FROM EMP D
WHERE D.DEPTNO = E.DEPTNO);
상호연관 Query
(Correlated
SubQuery)
9
10. WITH
[InLine_View 이름 1] AS (
),
[InLine_View 이름 2] AS (
)
[ InLine_View 이름 n] AS ( )
(SELECT col1
FROM table1
WHERE col1);
(SELECT col1
FROM InLine_View 이름 1
WHERE col1 >
);
(SELECT col1
FROM InLine_View 이름 2
WHERE col1);
(SELECT col1
FROM table2
WHERE col1);
1
2
3
4
WITH 문
10
SQL(STRUCTURE QUERY LANGUAGE) 은 1992 년 이전에 표준으로 설정된 후 꾸준한 발전을 해 왔습니다 . 그리고 , 오라클 데이터베이스는 오라클 이전버전 (v6, v7, v8.x) 에서 표준 SQL-1992 를 기본으로 채택하여 보다 쉽고 간편하게 데이터의 조작을 도와왔습니다 . 1999 년 표준협회는 새로운 버전의 SQL-1999 를 발표하였고 이에 오라클사는 오라클 9i 버전에서 SQL-1999 를 기본기능으로 채택하게 되었습니다 . 그 동안 사용되던 SQL 의 문법들은 대부분 그대로 사용이 가능하며 새로운 SQL-1999 의 문법들이 추가되었습니다 . 그럼 , SQL 의 향상된 기능을 알아보도록 합시다 .
JOIN 하나의 테이블로는 원하는 컬럼 정보를 참조할 수 없는 경우에 관련된 테이블을 논리적으로 결합하여 원하는 컬럼을 참조할 수 있습니다 . 이러한 방법을 JOIN 이라고 합니다 . 단 , 논리적으로 결합되는 2 개 이상의 테이블에는 반드시 공통 컬럼이 존재해야 하며 2 개의 컬럼은 데이터 타입과 공통된 데이터를 포함해야 합니다 . SQL> SELECT empno, ename, deptno EMP 테이블에는 부서명을 참조할 수 있는 컬럼이 존재하지 않습니다 FROM EMP; SQL> SELECT emp.empno, emp.ename, dept.dname FROM EMP, DEPT 부서명을 참조하기 위해 DEPT 테이블을 논리적으로 결합합니다 . WHERE EMP.DEPTNO = DEPT.DEPTNO; 오라클 이전버전 (v6,v7,v8.x) 에서는 EQUI 조인 , Non-Equi 조인 , Outer 조인 , Self 조인 4 가지 유형의 조인기법이 소개되었지만 오라클 9i 버전에서는 CROSS 조인 , NATURAL 조인 , USING 절 조인 , THREE-WAY 조인과 같은 조인기법이 소개되고 있습니다 . 뭔가 용어에서 느낄 수 있는 새로운 뭔가를 기대할 수 있지만 그리 많은 변화가 생긴 것은 아닙니다 . 용어의 변화와 함께 몇 가지 기능 만이 추가된 것입니다 .
이 문법은은 SQL-1999 에서 제공하는 조인기법에 대한 문법을 정리한 것입니다 . 먼저 , 문법을 한번쯤 살펴보고 각 조인기법을 알아봅시다 .
. CROSS 조인 ① CROSS 조인기법을 사용할 때 적용하는 문법입니다 . 이 조인기법은 오라클 이전 버전에서 사용되던 카르테시안 (CARTESIAN) 조인기법의 명칭이 CROSS 조인으로 바뀐 것이며 그 기능상의 차이는 전혀 없습니다 . CROSS 조인이란 2 개이상의 테이블이 조인될 때 WHERE 절에 의해 공통되는 컬럼에 의한 결합이 발생하지 않는 경우를 의미합니다 . 즉 , 공통되는 컬럼이 정의되지 않았다는 것은 테이블 전체 행의 전체 컬럼이 조인에 사용된 다는 것을 의미하기 때문에 2 개 이상의 테이블에 존재하는 모든 데이터가 검색결과가 되는 경우입니다 . 이러한 경우는 주로 개발자가 실수로 WHERE 절을 사용하지 않을 때 발생하며 아주 특별한 경우 2 개 이상의 모든 데이터를 참조해야 하는 경우 사용될 수 도 있습니다 . SQL> SELECT e.empno, e.ename, d.dname FROM EMP E, DEPT D; 이 문법은 오라클 이전버전에서 카르테시안 (CARTESIAN) 조인기법으로 실행되던 방법입니다 . FROM 절에 정의된 테이블의 공통 컬럼에 대해 WHERE 절이 생략되어 있죠 ?? 자 그럼 이번에는 오라클 9i 에서 제공하는 CROSS 조인에 대해서 알아봅시다 . 참 ! 헷갈리죠 ? 카르테시안 (CARTESIAN) 조인과 CROSS 조인은 같은 의미의 용어입니다 . 아시겠죠 ? SQL> SELECT empno, ename FROM emp CROSS JOIN dept; . NATURAL JOIN ② 이 조인기법은 오라클 이전버전에서 사용되던 EQUI 조인기법을 의미합니다 . 오라클 9i 버전에서 그 명칭이 바뀌었고 문법적인 변화가 생겼으며 기능상의 차이는 없습니다 . 2 개 이상의 테이블이 공통되는 컬럼에 의해 논리적으로 결합되는 조인 기법입니다 . 이러한 경우 WHERE 절에 사용된 공통된 컬럼들이 동등 연산자 (Equal,=) 에 의해 비교되면 NATURAL 조인이라고 합니다 . SQL> SELECT e.empno, e.ename, d.dname FROM EMP E, DEPT D WHERE e.deptno = d.deptno; 이 문법은 오라클 이전버전에서 EQUI 조인기법으로 실행되던 방법입니다 . EMP 테이블의 부서번호 컬럼과 DEPT 테이블의 부서번호 컬럼은 서로 같은 데이터 유형 , 같은 데이터를 가지고 있으며 논리적 결합에 의해 부서명 컬럼 정보를 사용자는 참조할 수 있게 됩니다 . 오라클 9i 버전에서는 NATURAL 조인에서 WHERE 절을 사용하지 않으며 JOIN ~ USING ~ 절을 통해 공통 컬럼을 비교하게 됩니다 . 만약 , USING~ 을 사용하지 않으면 오라클 서버는 각 테이블에 공통된 컬럼을 자동으로 검색하여 비교하게 됩니다 . SQL> SELECT empno, ename, dname FROM emp NATURAL JOIN dept; . USING 절 조인 NATURAL 조인시 공통 컬럼을 정의하지 않으면 오라클 서버는 해당 테이블의 모든 컬럼을 대상으로 공통 컬럼을 분석하여 논리적으로 결합해 줍니다 . USING 절을 사용하면 USING 절에 정의된 컬럼을 기준으로 NATURAL 조인이 발생합니다 . SQL> SELECT e.empno, e.ename, d.dname FROM emp e JOIN dept d USING (deptno);
. USING 절 JOIN 오라클 이전 버전에서 사용되던 SELF 조인기법과 동일한 기능을 가지고 있습니다 . 하나의 테이블이 2 번 이상 반복적으로 사용되고 어떤 컬럼이 참조해야 할 컬럼이 자신의 테이블에 있는 다른 컬럼 인 경우를 의미합니다 . 다음은 오라클 이전 버전에서 SELF 조인하던 방법을 JOIN~ON 절을 통해 조인하고 있습니다 . 먼저 , 이전 버전에 구현하는 방법입니다 . SQL> SELECT e.empno, e.ename, e.mgr, d.empno FROM EMP E, EMP D WHERE e.empno = d.empno; 이번에는 , 오라클 9i 버전에서 구현하는 방법입니다 SQL> SELECT e.empno, e.ename, e.mgr, d.empno FROM EMP E JOIN EMP D ON e.empno = d.empno; . OUTER JOIN ④ OUTER 조인은 오라클 이전 버전에서도 사용되던 조인 기법입니다 . 이 기법은 2 개이상의 테이블이 조인될 때 어느 한쪽의 테이블에는 해당하는 데이터가 존재하는데 다른 쪽 테이블에는 데이터가 존재하지 않는 경우 그 데이터는 출력되지 않는 문제를 해결하기 위해 사용되는 조인 기법입니다 . 데이터가 존재하지 않는 쪽 테이블에 (+) 기호를 정의하면 데이터가 존재하는 테이블의 데이터 만 화면에 출력됩니다 . 다음은 오라클 이전 버전에서 사용하던 OUTER 조인을 구현하는 방법입니다 . SQL> SELECT e.empno, e.ename, e.mgr, d.empno FROM EMP E, EMP D WHERE e.empno(+) = d.empno; 이번에는 오라클 9i 버전에서 구현하는 방법입니다 . SQL> SELECT e.empno, e.ename, e.mgr, d.empno FROM EMP E LEFT OUTER JOIN DEPT D ON e.empno = d.empno; 오라클 9i 버전에서 제공하는 OUTER 조인은 3 가지 유형이 있습니다 . 지금까지 설명되었던 조인방법을 LEFT OUTER 조인이라고 합니다 . 즉 , 2 개이상의 테이블이 논리적으로 결합될 때 왼쪽에 배치된 (FROM 절에 기술된 테이블의 순서 ) 테이블에 데이터가 존재하지 않는 경우를 의미합니다 . 만약에 , 오른쪽에 배치된 테이블에 데이터가 존재하지 않는다면 RIGHT OUTER 조인이라고 하고 , 양쪽 모두 데이터가 존재하지 않는다면 FULL OUTER 조인 이라고 합니다 . 다음은 RIGHT OUTER JOIN 예제입니다 . SQL> SELECT e.empno, e.ename, e.mgr, d.empno FROM EMP E RIGHT OUTER JOIN DEPT D ON e.empno = d.empno; 다음은 RIGHT OUTER JOIN 예제입니다 . ; SQL> SELECT e.empno, e.ename, e.mgr, d.empno FROM EMP E FULL OUTER JOIN DEPT D ON e.empno = d.empno;
. SUB-QUERY 하나의 SQL 문장의 절에 부속된 또 다른 SELECT 문장으로 , 두 번의 질의를 수행해야 만 얻을 수 있는 결과를 한번의 질의로 해결할 수 있는 문장입니다 . MAIN-QUERY 는 OUTER-QUERY 라고도 하며 실제로 실행될 SQL 문을 가지고 있습니다 . SUB-QUERY 에 의해 실행된 SQL 문의 결과에 의해 MAIN-QUERY 는 실행됩니다 . SUB-QUERY 는 INNER-QUERY 라고도 합니다 . - 연산자의 오른쪽에 위치하며 괄호로 묶여져 사용됩니다 . - 질의가 지정되지 않은 값을 근거로 할 때 유용합니다 . - SUB-QUERY 는 MAIN-QUERY 의 조건으로 사용됩니다 . - SUB-QUERY 의 결과는 MAIN-QUERY 에 의해 사용됩니다 . - 실행순서는 대부분의 경우는 SUB-QUERY 가 먼저 실행되고 그 결과를 MAIN-QUERY 에 전달하여 실행합니다 . - SUB-QUERY 는 MAIN-QUERY 의 다음 위치에 사용될 수 있습니다 . . SELECT 절 . SELECT/DELETE/UPDATE 문장의 FROM 절 . WHERE 절 . HAVING 절 . INSERT 문의 INTO 절 /UPDATE 문의 SET 절 - SUB-QUERY 에는 ORDER BY 절을 사용할 수 없습니다 (SELECT/DELETE/UPDATE 문장의 FROM 절에 사용하는 경우에는 제외 ) ( 예제 ) 다음은 2 개의 SQL 문을 통해 MARTIN 과 같은 직무를 가진 사원정보를 사원 테이블에서 검색합니다 . SQL> SELECT job FROM emp WHERE empno = 7900; JOB ------------- ANALYST SQL> SELECT * FROM EMP WHERE job = ‘ ANALYST ’ ; - 다음은 SUB-QUERY 를 이용한 검색 방법입니다 . SQL> SELECT * FROM EMP WHERE job = (SELECT job FROM emp WHERE empno = 7900);
. SUB-QUERY 의 종류 SUB-QUERY 는 4 가지 종류가 있습니다 . 단일 행 SUB-QUERY, 복수 행 SUB-QUERY, 복수 컬럼 SUB-QUERY, 상호관련 SUB-QUERY 각 각의 경우에 대해서 알아볼까요 . . 단일 행 SUB-QUERY 첫 번째로 단일 행 SUB-QUERY 는 그 실행결과가 하나의 컬럼 , 하나의 행을 리턴 해 주는 경우를 의미합니다 , 또한 그 결과와 비교를 해야 하기 때문에 =, <, >, <=, >= 와 같은 비교 연산자가 사용됩니다 . SQL> SELECT * FROM EMP WHERE sal => (SELECT sal FROM emp WHERE empno = 7900); < 주의사항 > 1) 단일 행 SUB-QUERY 가 여러 개의 결과를 리턴하는 경우 에러가 발생합니다 . SQL> SELECT ename, sal FROM emp WHERE sal = (SELECT sal FROM emp WHERE deptno = 10); ERROR------------------ 2) SUB-QUERY 에 의해 리턴되는 결과의 컬럼 수와 MAIN-QUERY 에서 비교되는 컬럼 수가 일치하지 않으면 에러가 발생합니다 . SQL> SELECT ename, sal FROM emp WHERE sal = (SELECT sal, comm FROM emp WHERE deptno = 10); ERROR------------------ 3) SUB-QUERY 의 WHERE 절에 복수 행 함수를 사용할 수 없습니다 . SQL> SELECT ename, sal FROM emp WHERE sal = (SELECT sal FROM emp WHERE sal > AVG(sal); ERROR------------------ . 복수 행 SUB-QUERY 두 번째로 복수 행 SUB-QUERY 는 그 실행결과가 여러 개의 행을 리턴 해 주는 경우를 의미합니다 . 그 결과가 복수 개의 행과 비교해야 하기 때문에 IN 연산자가 사용합니다 . SQL> SELECT * FROM EMP WHERE sal =ANY (SELECT sal FROM emp WHERE deptno = 10); < 다중 행 연산자 > SUB-QUERY 의 결과가 여러 개 인 경우에는 반드시 다중 행 연산자를 이용하여 MAIN-QUERY 의 컬럼과 비교해야 합니다 . 1) IN 연산자 : SUB-QUERY 에 의해 리턴되는 값 중에서 조건에 해당하는 행이 있으면 출력해 줍니다 . SQL> SELECT ename, sal FROM emp WHERE sal IN (SELECT MAX(sal) FROM emp GROUP BY deptno; 2) ANY 연산자 : SUB-QUERY 에 의해 리턴되는 값 중에서 하나 이상을 만족하는 행이 있으면 출력해 줍니다 . SQL> SELECT empno, ename, job, sal FROM emp WHERE sal =ANY (SELECT sal FROM emp WHERE job = ‘ MANAGER ’ ); 2) ALL 연산자 : SUB-QUERY 에 의해 리턴되는 값 모두를 만족하는 행이 있으면 출력해 줍니다 . SQL> SELECT empno, ename, job, sal FROM emp WHERE sal =ALL (SELECT sal FROM emp WHERE job = ‘ MANAGER ’ );
. 복수 컬럼 SUB-QUERY 세 번째로 복수 컬럼 SUB-QUERY 는 실행결과가 복수개의 컬럼 , 복수개의 행을 리턴해 줍니다 . SQL> SELECT ename, deotno, NVL(comm, -1) FROM emp WHERE (sal, NVL(comm, -1) IN (SELECT sal,NVL(comm, -1) FROM emp WHERE deptno = 30); - 각 부서의 평균 급여보다 많이 받는 사원을 출력합니다 . SQL> SELECT ename, sal . 상호관련 SUB-QUERY 마지막으로 , 상호연관 SUB-QUERY 는 MAIN-QUERY 절에 사용된 테이블이 SUB-QUERY 절에 다시 재 사용되는 경우의 SUB-QUERY 를 말합니다 . 이러한 SUB-QUERY 의 사용은 사용자의 SQL 문을 보다 쉽고 간편하게 해주는 장점을 가지고 있지만 한편으론 성능을 저하시키는 단점을 가지고 있기도 합니다 . SQL> SELECT E.EMPNO, E.ENAME, E.DEPTNO FROM EMP E WHERE SAL > (SELECT AVG(SAL) FROM EMP D WHERE D.DEPTNO = E.DEPTNO);
. WITH 문 오라클 9i 에서 제공하는 WITH 절은 여러 개의 SUB-QUERY 가 하나의 MAIN-QUERY 에서 사용될 때 생기는 복잡성을 보다 간결하게 정의하여 사용함으로서 발생할 수 있는 성능저하 현상을 방지할 수 있습니다 . 먼저 , 하나의 MAIN-QUERY 에 정의될 SUB-QUERY 를 WITH 절과 함께 ①과 ②와 같이 선언하십시오 . 각 SUB-QUERY 가 정의될 때 SUB-QUERY 를 대신 할 인라인 뷰의 이름을 사용자가 적절하게 정의하십시오 . 여러 개의 SUB-QUERY 가 사용된다면 순서대로 선언하면 됩니다 . 참 ~ 만약에 어떤 SUB-QUERY 가 다른 SUB-QUERY 를 참조해야 하는 경우에는 참조되는 SUB-QUERY 가 참조하는 SUB-QUERY 보다 우선적으로 선언되어야 합니다 . ③ SUB-QUERY 의 선언이 끝나면 실제로 실행될 MAIN-QUERY 절을 작성하십시오 . 이때 필요한 SUB-QUERY 가 있다면 ④ 선언된 SUB-QUERY(①,②) 로부터 인라인 뷰의 이름으로 새로운 SUB-QUERY 를 작성하십시오 . 이제 다음과 같이 따라 해 보세요 !! SQL> WITH dept_costs AS (SELECT d.dname, SUM(e.sal) as dept_total FROM emp e, dept d WHERE e.deptno = d.deptno GROUP BY e.deptno), avg_cost AS (SELECT SUM(dept_totoal / COUNT(*) as dept_avg FROM dept_costs) SELECT * FROM dept_costs WHERE dept_total > (SELECT dept_avg FROM avg-cost) ORDER BY deptno;
① 과 ②는 ③ MAI N-QUERY 와 ④ SUB -QUERY 에서 사용할 쿼리들을 WITH 절을 통해 미리 선언한 것입니다 .