-- 1. 그룹함수 사용 안할 때는 리턴하는 값이 없음
SELECT 1
FROM DEPT
WHERE 1 = 2
;
no rows selected
-- 2. 그룹함수를 사용하면 값을 리턴함
SELECT MIN(DEPTNO)
FROM DEPT
WHERE 1 = 2
;
MIN(DEPTNO)
-----------
1 row selected.
-- 3. 스칼라 서브쿼리 테스트(일치하는 값이 없을 경우 NULL 리턴함)
-- EMP:DEPT = M:1 관계에서 M 대상을 올리다보니 GROUP BY 을 추가함
SELECT D.DEPTNO,
(SELECT MIN(EMPNO)
FROM EMP
WHERE DEPTNO = D.DEPTNO) EMPNO
FROM DEPT D
ORDER BY D.DEPTNO
;
DEPTNO EMPNO
---------- ----------
10 1
20 10
30 100
40 1000
50 10000
60 100000
70
80
90
9 rows selected.
SELECT D.DEPTNO,
E.EMPNO
FROM DEPT D,
(SELECT DEPTNO,
MIN(EMPNO) EMPNO
FROM EMP
GROUP BY DEPTNO) E
WHERE D.DEPTNO = E.DEPTNO(+)
ORDER BY D.DEPTNO
;
DEPTNO EMPNO
---------- ----------
10 1
20 10
30 100
40 1000
50 10000
60 100000
70
80
90
9 rows selected.
-- 1. 2개의 그룹함수 인라인뷰와 Outer 조인이 되어 View Merging이 안된다.
SELECT T_1.SUM_EMPNO SUM_EMPNO_1,
T_2.SUM_EMPNO SUM_EMPNO_2,
E.HIREDATE,
E.DEPTNO
FROM (SELECT E_1.EMPNO,
SUM(E_1.EMPNO) SUM_EMPNO
FROM EMP E_1
GROUP BY E_1.EMPNO) T_1,
(SELECT E_2.EMPNO,
SUM(E_2.EMPNO) SUM_EMPNO
FROM EMP E_2
GROUP BY E_2.EMPNO) T_2,
EMP E
WHERE E.EMPNO = T_1.EMPNO(+)
AND E.EMPNO = T_2.EMPNO(+)
AND E.DEPTNO = 10
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.006 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.610 0.607 1 811 0 9
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.610 0.612 1 811 0 9
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
9 HASH JOIN OUTER (cr=811 pr=1 pw=0 time=493640 us)
9 HASH JOIN OUTER (cr=407 pr=1 pw=0 time=203353 us)
9 TABLE ACCESS BY INDEX ROWID EMP (cr=3 pr=1 pw=0 time=11482 us)
9 INDEX RANGE SCAN EMP_N1 (cr=2 pr=1 pw=0 time=11433 us)(Object ID 19837982)
100000 VIEW (cr=404 pr=0 pw=0 time=289825 us)
100000 HASH GROUP BY (cr=404 pr=0 pw=0 time=289818 us)
100000 TABLE ACCESS FULL EMP (cr=404 pr=0 pw=0 time=115 us)
100000 VIEW (cr=404 pr=0 pw=0 time=274989 us)
100000 HASH GROUP BY (cr=404 pr=0 pw=0 time=174985 us)
100000 TABLE ACCESS FULL EMP (cr=404 pr=0 pw=0 time=115 us)
;
-- 2. 이를 극복하기 위해 스칼라 서브쿼리로 올림
SELECT (SELECT SUM(E_1.EMPNO) SUM_EMPNO
FROM EMP E_1
WHERE E_1.EMPNO = E.EMPNO) SUM_EMPNO_1,
(SELECT SUM(E_2.EMPNO) SUM_EMPNO
FROM EMP E_2
WHERE E_2.EMPNO = E.EMPNO) SUM_EMPNO_2,
E.HIREDATE,
E.DEPTNO
FROM EMP E
WHERE E.DEPTNO = 10
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.010 0.004 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.000 0.066 2 27 0 9
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.010 0.070 2 27 0 9
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
9 SORT AGGREGATE (cr=11 pr=1 pw=0 time=50528 us)
9 INDEX UNIQUE SCAN EMP_U1 (cr=11 pr=1 pw=0 time=50440 us)(Object ID 19837981)
9 SORT AGGREGATE (cr=11 pr=0 pw=0 time=152 us)
9 INDEX UNIQUE SCAN EMP_U1 (cr=11 pr=0 pw=0 time=102 us)(Object ID 19837981)
9 TABLE ACCESS BY INDEX ROWID EMP (cr=5 pr=1 pw=0 time=15032 us)
9 INDEX RANGE SCAN EMP_N1 (cr=3 pr=1 pw=0 time=15172 us)(Object ID 19837982)
-- 1. 인라인뷰 안의 스칼라 서브쿼리를 뷰 밖에서 조건으로 사용할 경우
SELECT EMPNO,
DEPT_NO
FROM (SELECT E.EMPNO,
(SELECT D.DEPTNO
FROM DEPT D
WHERE D.DEPTNO = E.DEPTNO) DEPT_NO
FROM EMP E)
WHERE DEPT_NO = 10
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.004 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.110 0.119 0 407 0 9
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.110 0.123 0 407 0 9
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
6 INDEX UNIQUE SCAN DEPT_U1 (cr=2 pr=0 pw=0 time=81 us)(Object ID 19837985)
9 FILTER (cr=407 pr=0 pw=0 time=186 us)
100000 TABLE ACCESS FULL EMP (cr=405 pr=0 pw=0 time=100112 us)
6 INDEX UNIQUE SCAN DEPT_U1 (cr=2 pr=0 pw=0 time=81 us)(Object ID 19837985)
;
-- 2. 스칼라 서브쿼리를 Outer 조인으로 내려서 극복
SELECT EMPNO,
DEPT_NO
FROM (SELECT E.EMPNO,
D.DEPTNO DEPT_NO
FROM EMP E,
DEPT D
WHERE D.DEPTNO = E.DEPTNO(+))
WHERE DEPT_NO = 10
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.010 0.004 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.000 0.017 1 6 0 9
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.010 0.021 1 6 0 9
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
9 NESTED LOOPS OUTER (cr=6 pr=1 pw=0 time=16862 us)
1 INDEX UNIQUE SCAN DEPT_U1 (cr=1 pr=0 pw=0 time=39 us)(Object ID 19837985)
9 TABLE ACCESS BY INDEX ROWID EMP (cr=5 pr=1 pw=0 time=16815 us)
9 INDEX RANGE SCAN EMP_N1 (cr=3 pr=1 pw=0 time=16904 us)(Object ID 19837982)
-- 1. 스칼라 서브쿼리에 IN절이 있는 경우
SELECT EMPNO,
DEPT_NO
FROM (SELECT E.EMPNO,
(SELECT D.DEPTNO
FROM DEPT D
WHERE D.DEPTNO = E.DEPTNO
AND D.DNAME IN ('SALES_1', 'SALES_2', 'SALES_3')) DEPT_NO
FROM EMP E)
WHERE DEPT_NO = 10
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.004 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.110 0.110 0 413 0 9
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.110 0.114 0 413 0 9
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
3 TABLE ACCESS BY INDEX ROWID DEPT (cr=8 pr=0 pw=0 time=187 us)
6 INDEX UNIQUE SCAN DEPT_U1 (cr=2 pr=0 pw=0 time=77 us)(Object ID 19837985)
9 FILTER (cr=413 pr=0 pw=0 time=201 us)
100000 TABLE ACCESS FULL EMP (cr=405 pr=0 pw=0 time=100107 us)
3 TABLE ACCESS BY INDEX ROWID DEPT (cr=8 pr=0 pw=0 time=187 us)
6 INDEX UNIQUE SCAN DEPT_U1 (cr=2 pr=0 pw=0 time=77 us)(Object ID 19837985)
;
-- 2. 스칼라 서브쿼리의 IN절을 Outer 조인으로 내리지만 결국 구문 에러남
SELECT EMPNO,
DEPT_NO
FROM (SELECT E.EMPNO,
D.DEPTNO DEPT_NO
FROM EMP E,
DEPT D
WHERE D.DEPTNO = E.DEPTNO(+)
AND D.DNAME(+) IN ('SALES_1', 'SALES_2', 'SALES_3'))
WHERE DEPT_NO = 10
;
AND D.DNAME(+) IN ('SALES_1', 'SALES_2', 'SALES_3') )
*
ERROR at line 8:
ORA-01719: outer join operator (+) not allowed in operand of OR or IN
-- 3. DECODE 구문을 이용하여 해결
SELECT EMPNO,
DEPT_NO
FROM (SELECT E.EMPNO,
D.DEPTNO DEPT_NO
FROM EMP E,
DEPT D
WHERE D.DEPTNO = E.DEPTNO(+)
--AND D.DNAME(+) IN ('SALES_1', 'SALES_2', 'SALES_3')
AND DECODE(D.DNAME(+), 'SALES_1', 1,
'SALES_2', 1,
'SALES_3', 1) = 1)
WHERE DEPT_NO = 10
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.004 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.000 0.010 1 7 0 9
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.000 0.014 1 7 0 9
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
9 NESTED LOOPS OUTER (cr=7 pr=1 pw=0 time=10393 us)
1 TABLE ACCESS BY INDEX ROWID DEPT (cr=2 pr=0 pw=0 time=70 us)
1 INDEX UNIQUE SCAN DEPT_U1 (cr=1 pr=0 pw=0 time=29 us)(Object ID 19837985)
9 TABLE ACCESS BY INDEX ROWID EMP (cr=5 pr=1 pw=0 time=10316 us)
9 INDEX RANGE SCAN EMP_N1 (cr=3 pr=1 pw=0 time=10390 us)(Object ID 19837982)
SELECT EMPNO,
ENAME,
HIREDATE,
(SELECT GET_DNAME(DEPTNO) FROM DUAL) DNAME
FROM EMP E
WHERE HIREDATE :1 AND :2
;
SELECT DEPTNO,
DNAME,
TO_NUMBER(SUBSTR(EMPNO, 1, 7)) AVG_EMPNO,
TO_NUMBER(SUBSTR(EMPNO, 8, 15)) MIN_EMPNO,
TO_NUMBER(SUBSTR(EMPNO, 15)) MAX_EMPNO
FROM (SELECT D.DEPTNO,
D.DNAME,
(SELECT LPAD(AVG(EMPNO), 7) || LPAD(MIN(EMPNO), 7) || MAX(EMPNO)
FROM EMP
WHERE DEPTNO = D.DEPTNO) EMPNO
FROM DEPT D)
;
DEPTNO DNAME AVG_EMPNO MIN_EMPNO MAX_EMPNO
---------- ------- ---------- ---------- ----------
10 SALES_1 5 19 9
20 SALES_2 54.5 1099 99
30 SALES_3 549.5 100999 999
40 SALES_4 5499.5 10009999 9999
50 SALES_5 54999.5 1000099999 99999
60 SALES_6 100000 1.0000E+11 100000
70 SALES_7
80 SALES_8
90 SALES_9
9 rows selected.
-- 1. 오브젝트 타입 생성
CREATE OR REPLACE TYPE EMPNO_TYPE AS OBJECT
(AVG_EMPNO NUMBER, MIN_EMPNO NUMBER, MAX_EMPNO NUMBER)
/
Type created.
-- 2. 오브젝트 타입 활용하여 멀티 컬럼 리턴
SELECT DEPTNO,
DNAME,
A.EMPNO.AVG_EMPNO,
A.EMPNO.MIN_EMPNO,
A.EMPNO.MAX_EMPNO
FROM (SELECT D.DEPTNO,
D.DNAME,
(SELECT EMPNO_TYPE(AVG(EMPNO), MIN(EMPNO), MAX(EMPNO))
FROM EMP
WHERE DEPTNO = D.DEPTNO) EMPNO
FROM DEPT D) A
;
DEPTNO DNAME EMPNO.AVG_EMPNO EMPNO.MIN_EMPNO EMPNO.MAX_EMPNO
---------- ------- --------------- --------------- ---------------
10 SALES_1 5 1 9
20 SALES_2 54.5 10 99
30 SALES_3 549.5 100 999
40 SALES_4 5499.5 1000 9999
50 SALES_5 54999.5 10000 99999
60 SALES_6 100000 100000 100000
70 SALES_7
80 SALES_8
90 SALES_9
9 rows selected.
- 강좌 URL : http://www.gurubee.net/lecture/3212
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.