SELECT x.자재코드,x.자재명,x.규격,x.안전재고,y.재고수량
FROM 자재 x, 자재일일재고 y
WHERE y.자재코드 = x.자재코드
AND y.년월일 = to_char(sysdate, 'yyyymmdd')
AND x.자재코드 IN (SELECT 자재코드
FROM 구매의뢰
WHERE 진행상태 = '발주중'
AND 출고희망일자 between to_char(sysdate,'yyyymmdd')
And to_char(sysdate+6,'yyyymmdd'));
NESTED LOOPS
VIEW
SORT(UNIQUE)* --유일한 값을 만들기 위한 정렬 작업이 내부적으로 일어난다
TABLE ACCESS (BY ROWID) OF '구매의뢰'
INDEX (RANGE SCAN) OF '인덱수1'
TABLE ACCESS (BY ROWID) OF '자재'
INDEX (UNIQUE SCAN) OF '자재_PK'
SELECT 사번,성명,주소,생년월일,입사일...
FROM 사원 x,부서 y
WHERE x.부서코드 = y.부서코드
AND x.입사일 >= '19970101'
AND y.지역 = '경기도';
SELECT 사번,성명,주소,생년월일,입사일...
FROM 사원
WHERE 입사일 >= '19970101'
AND 부서코드 IN (SELECT 부서코드
FROM 부서
WHERE 지역 = '경기도)
SELECT STATEMENT
NESTED LOOPS
TABLE ACCESS (BY ROWID) OF '사원'
INDEX (RANGE SCAN) OF '입사일_INDEX' (NON UNIQUE)
TABLE ACCESS (BY ROWID) OF '부서'
INDEX (UNIQUE SCAN) OF '부서_PK' (UNIQUE)
SELECT 부서코드,부서명,관리자,설립일,지역,...
FROM 부서
WHERE 지역 = '경기도'
AND 부서코드 IN (SELECT 부서코드
FROM 사원
WHERE 입사일 >= '19970101');
SELECT *distinct* y.부서코드,부서명,관리자,설립일,지역,...
FROM 사원 x,부서 y
WHERE x.부서코드 = y.부서코드
AND 입사일 >= '19970101'
AND 지역 = ' 경기도'
SELECT 자재코드, 자재명, 규격, 안전재고, .................
FROM 자재 x
WHERE 자재구분 = '배관자재'
and 안전재고 >= (SELECT 재고수량
FROM 자재일일재고
WHERE y.자재코드 = x.자재코드
and y.년월일 = to_char(sysdate, 'yyyymmdd'));
Execution Plan
\-------------------------------------------------------\-
SELECT STATEMENT
{color:#cc0000}{*}FILTER{*}{color}\\
TABLE ACCESS (BY ROWID) OF '자재'
INDEX (RANGE SCAN) OF '자재구분_INDEX' (NON-UNIQUE)
TABLE ACCESS (BY ROWID) OF '자재일일재고'
INDEX (RANGE SCAN) OF '년월일_INDEX' (NON-UNIQUE)
확인자 역할을 하는 서브쿼리: 수행시간 1600초 | 제공자 역할을 하는 서브쿼리: 수행시간 0.1초 |
---|---|
UPDATE 청구 x SET 입금액 = nvl(입금액,0) + :in_amt WHERE 청구년월 = '199803' and 고객번호 IN (SELECT 고객번호 FROM 고객 y WHERE 납입자 = :in_cust and y.고객번호 = x.고객번호 ); | UPDATE 청구 x SET 입금액 = nvl(입금액,0) + :in_amt WHERE 청구년월 = '199803' and 고객번호 IN (SELECT 고객번호 FROM 고객 y WHERE 납입자 = :in_cust and y.고객번호 = x.고객번호 ); |
SELECT *
FROM TAB1
WHERE DEPTNO = '1100'
and SALDATE IN (SELECT YMD \|\| '' <= 서브쿼리가 확인자 역할을 한다면, 컬럼에 \|\|'' 로 가공하여 제공자역할을 수행하도록한다.
FROM YMD_DUAL
WHERE YMD between '19980301' and '19980312' )
and ITEM LIKE 'ABC%' ;
SELECT *
FROM ORDER x
WHERE ORDDATE LIKE '9706%'
AND EXISTS (SELECT 'X'
FROM DEPT y
WHERE y.DEPTNO = x.SALDEPT
AND y.TYPE1='1')
ROWS Execution Plan
\--\-- --\--\------------------------------------------------\-
3200 FILTER
3200 TABLE ACCESS (BY ROWID) OF 'ORDER'
3201 INDEX (RANGE SCAN) OF 'ORDDATE_INDEX' (NON_UNIQUE)
10 TABLE ACCESS (BY ROWID) OF 'DEPT'
10 INDEX (UNIQUE SCAN) OF 'DEPT_PK' (UIQUE)
① 먼저 ORDDATE_INDEX에서 '9706%'를 만족하는 첫번째 로우를 읽고 그 ROWID로 ORDER 테이블의 해당 로우를 액세스한다.
② 그 로우가 가지고 있는 SALDEPT와 버퍼에 있는 DEPT와 비교한 결과가 같지 않으므로 DEPT 테이블의 기본키를 이용해 액세스한 후 체크한다. 체크결과 조건을 만족하면 운반단위에 태우고 아니면 버린다
③ 액세스한 DEPT 네이블의 비교컬럼값들을 버퍼에 저장한다.
④ ORDDATE_IDEX의 두번째 로우에 대한 ORDER 테이블 로우를 액세스한 후 버퍼와 체크한다. 이때 ORDER 테이블의 SALDEPT와 버퍼의 DEPT가 동일하면 버ㅓ와의 비교만 수행하며, DEPT 테이블은 액세스하지 않는다. 버퍼의 DEPT와 일치하지 않을 때만 DEPT테이블을 액세스하여 비교하고 그 값을 다시 버퍼에 저장한다. 버퍼는 하나의 값만 저장할 수 있으므로 앞서 저장된 값은 갱신된다.
⑤ 이와 같은 방법으로 ORDDATE_INDEX 의 처리범위가 완료될 때까지 수행한다
구분 | 인라인 뷰 조인 | UNION,GROUP | 사용자지정 저장형 함수 | 서브쿼리 |
---|---|---|---|---|
M:M관계의 데이터 연결 | ○ | ○ | ○ | ○ |
결과의 추출을 원할 때 | ○ | ○ | ○ | X |
다양한 추출컬럼이 필요할 때 | ○ | ○ | △ | X |
양측 OUTER 조인 | X | ○ | X | X |
독자적으로 범위를 줄일 수 있을 때 | ○ | ○ | ○ | ○ |
다른 쪽에서 결과를 받는 것이 유리 | X | X | ○ | ○ |
배타적 관계의 연결 | X | ○ | ○ | △ |
연결할 집합이 유사하지 않을 때 | ○ | △ | ○ | ○ |
부분범위처리 | △ | X | ○ | △ |
기본키와 외부키가 아닌 경우의 연결 | ○ | ○ | ○ | ○ |
단순히 조건 체크만 원할 때 | △ | X | △ | ○ |
단순히 조건의 상수값만 제공할 때 | △ | X | △ | ○ |
SELECT x.COL1, x.COL2, min(x.COL4), min(x.COL5)
FROM TAB1 x, TAB2 y
WHERE x.COL1 = y.FLD1
and x.COL2 = y.FLD2
and x.COL3 between '1110' and '3999'
and y.FLD3 like '199803%'
GROUP BY COL1, COL2
HAVING sum(FLD4) > 0 ;
SELECT COL1, COL2, COL4, COL5
FROM TAB1
WHERE COL3 between '1110' and '3999'
and EXISTS (SELECT ' '
FROM TAB2
WHERE FLD1 = COL1
and FLD2 = COL2
and FLD3 like '199803%'
GROUP BY FLD1, FLD2
HAVING sum(FLD4) > 0);
SELECT *
FROM TAB1
WHERE COL1 >= ALL ( SELECT FLD1
FROM TAB2
WHERE FLD2 like 'ABC%' );
SELECT *
FROM TAB1
WHERE COL1 >= ( SELECT MAX(FLD1)
FROM TAB2
WHERE FLD2 like 'ABC%' );
SELECT *
FROM TAB1
WHERER COL1 >= ANY (SELECT FLD1
FROM TAB2
WHERE FLD2 like 'ABC%' );
SELECT *
FROM TAB1
WHERE COL1 >= ( SELECT MIN(FLD1)
FROM TAB2
WHERE FLD2 like 'ABC%' );
SELECT 종목, 고객번호, 변경회차, 변경일자, 금액
FROM 변경내역 x
WHERE 변경회차 = ( SELECT MAX(y.변경회차)
FROM 변경내역 y
WHERE y.고객번호 = x.고객번호
and y.변경일자 between '19980101' and '19980131' )
and 종목 = '15'
and 변경일자 between '19980101' and '19980131' ;
SELECT '15' 종목,
고객번호,
substr(추출값,1,3) 변경회차,
substr(추출값,1,3) 변경일자,
substr(추출값,1,3) 금액
FROM (SELECT 고객번호,
MAX(RPAD(변경회차,3)\|\|변경일자\|\|금액) 추출값
FROM 변경내역
WHERE 종목 = '15'
and 변경일자 between '19980101' and '19980131'
GROUP BY 고객번호);
- 강좌 URL : http://www.gurubee.net/lecture/2485
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.