CREATE TABLE TEST30 (KEY1 VARCHAR2(02),AMT NUMBER);
CREATE INDEX TEST30_I ON TEST30(KEY1);
INSERT INTO TEST30 VALUES ('A',123);
INSERT INTO TEST30 VALUES ('B',345);
INSERT INTO TEST30 VALUES ('C',357);
INSERT INTO TEST30 VALUES ('D',763);
INSERT INTO TEST30 VALUES ('E',843);
INSERT INTO TEST30 VALUES ('F',345);
INSERT INTO TEST30 VALUES ('G',235);
INSERT INTO TEST30 VALUES ('H',845);
INSERT INTO TEST30 VALUES ('I',652);
INSERT INTO TEST30 VALUES ('J',323);
CREATE TABLE TEST31 (KEY1 VARCHAR2(02),YM VARCHAR2(06), AMT1 NUMBER);
CREATE INDEX TEST31_I ON TEST31(KEY1,YM);
INSERT INTO TEST31 VALUES ('A','199905',23);
INSERT INTO TEST31 VALUES ('A','199906',43);
INSERT INTO TEST31 VALUES ('A','199907',56);
INSERT INTO TEST31 VALUES ('B','199906',23);
INSERT INTO TEST31 VALUES ('B','199907',43);
INSERT INTO TEST31 VALUES ('C','199908',56);
CREATE TABLE TEST32 (KEY1 VARCHAR2(02),YM VARCHAR2(06), AMT2 NUMBER);
CREATE INDEX TEST32_I ON TEST32(KEY1,YM);
INSERT INTO TEST32 VALUES ('B','199905',33);
INSERT INTO TEST32 VALUES ('C','199906',65);
INSERT INTO TEST32 VALUES ('D','199907',87);
INSERT INTO TEST32 VALUES ('D','199908',12);
INSERT INTO TEST32 VALUES ('E','199907',45);
INSERT INTO TEST32 VALUES ('E','199908',89);
CREATE TABLE TEST33 (KEY1 VARCHAR2(02),YM VARCHAR2(06), AMT3 NUMBER);
CREATE INDEX TEST33_I ON TEST33(KEY1,YM);
INSERT INTO TEST33 VALUES ('B','199905',76);
INSERT INTO TEST33 VALUES ('C','199906',98);
INSERT INTO TEST33 VALUES ('E','199907',21);
INSERT INTO TEST33 VALUES ('F','199908',54);
INSERT INTO TEST33 VALUES ('G','199907',87);
INSERT INTO TEST33 VALUES ('H','199908',85);
상호간 OUTER 조인의 해결방안
조건.
TEST30
열 이름 유형
--------- ----
KEY1 VARCHAR2(2)
AMT NUMBER
KEY1 AMT
---- --------
A 123
B 345
C 357
D 763
E 843
F 345
G 235
H 845
I 652
J 323
TEST31 TEST32 TEST33
열 이름 유형 열 이름 유형 열 이름 유형
--------- ---- --------- ---- --------- ----
KEY1 VARCHAR2(2) KEY1 VARCHAR2(2) KEY1 VARCHAR2(2)
YM VARCHAR2(6) YM VARCHAR2(6) YM VARCHAR2(6)
AMT1 NUMBER AMT2 NUMBER AMT3 NUMBER
KEY1 YM AMT1 KEY1 YM AMT2 KEY1 YM AMT3
---- ------ ------ ---- ------ ------ ---- ------ ------
A 199905 23 B 199905 33 B 199905 76
A 199906 43 C 199906 65 C 199906 98
A 199907 56 D 199907 87 E 199907 21
B 199906 23 D 199908 12 F 199908 54
B 199907 43 E 199907 45 G 199907 87
C 199908 56 E 199908 89 H 199908 85
문제.
TEST30의 KEY1을 FOREIGN KEY 로
TEST31부터 TEST33 까지가 KEY1과 YM을 PRIMARY KEY로 가지고 있는
다른 성격의 DATA를 관리하는 같은 구조의 테이블이다.
TEST31부터 TEST33까지에 DATAT가 존재하면 존재하는 모든 DATA를
YM과 KEY1순으로 정렬 하여
TEST30.AMT, TEST31.AMT1, TEST32.AMT2, TEST33.AMT3
을 보고싶다.
결과가 다음과 같이 나오면 되겠다.
YM KEY1 AMT AMT1 AMT2 AMT3
------ ---- ---------- ---------- ---------- ----------
199905 A 123 23
199905 B 345 33 76
199906 A 123 43
199906 B 345 23
199906 C 357 65 98
199907 A 123 56
199907 B 345 43
199907 D 763 87
199907 E 843 45 21
199907 G 235 87
199908 C 357 56
199908 D 763 12
199908 E 843 89
199908 F 345 54
199908 H 845 85
생각.
실제 설계에서는 피해가는 부분이지만 어쩔 수 없이 위와 같이
설계가 이루어지는 경우가 있다.
조건식에서 양방향 OUTER JOIN을 이용할 수 있다면 혹시 쉽게
해결할 수 있는 문제일지 모른다.
하지만 불행하게도 양방향 OUTER JOIN 은 먹혀들지를 않는다.
MASTER인 TEST30을 기준으로 OUTER 조인을 사용할 것인가?..
KEY1만 이라면 그렇게 할 수도 있을 것이다.
하지만 YM에 대해서는 또 어떻게 할 것인가?.
앞 주제중에 구조 DATA를 이용하는 주제가 있었다.
해결 방법은 그 방법과 흡사하다.
KEY1과 YM을 먼저 만들어 놓고 그것을 기준으로 OUTER 조인을
사용하면 된다.
복습하는 셈 치고 한번 직접 해보자.
결코 어려운 문제가 아니다.
해법.TEST31 부터 TESTT33 사이에 존재하는 KEY과 YM을 먼저 만들어보자.
31부터 33까지에서 KEY와 YM을 따로 읽어서 UNION 을 하게되면
두개의 KEY를 기준으로 UNIQUE한 DATA가 나온다.
SELECT YM,KEY1 FROM TEST31
UNION
SELECT YM,KEY1 FROM TEST32
UNION
SELECT YM,KEY1 FROM TEST33
YM KEY1
------ --
199905 A
199905 B
199906 A
199906 B
199906 C
199907 A
199907 B
199907 D
199907 E
199907 G
199908 C
199908 D
199908 E
199908 F
199908 H
여기까지 했으면 다했다.
이제 위의 DATASET을 기준으로 OUTER JOIN만 해 주면 된다.
SELECT A.YM,A.KEY1,B.AMT,C.AMT1,D.AMT2,E.AMT3
FROM (SELECT YM,KEY1 FROM TEST31
UNION
SELECT YM,KEY1 FROM TEST32
UNION
SELECT YM,KEY1 FROM TEST33) A,
TEST30 B,
TEST31 C,
TEST32 D,
TEST33 E
WHERE B.KEY1(+) = A.KEY1
AND C.KEY1(+) = A.KEY1
AND C.YM(+) = A.YM
AND D.KEY1(+) = A.KEY1
AND D.YM(+) = A.YM
AND E.KEY1(+) = A.KEY1
AND E.YM(+) = A.YM
결과는 문제의 답과 같다.
PLAN :
SELECT STATEMENT Optimizer=CHOOSE
NESTED LOOPS (OUTER)
NESTED LOOPS (OUTER)
NESTED LOOPS (OUTER)
NESTED LOOPS (OUTER)
VIEW
SORT (UNIQUE)
UNION-ALL
TABLE ACCESS (FULL) OF TEST31
TABLE ACCESS (FULL) OF TEST32
TABLE ACCESS (FULL) OF TEST33
TABLE ACCESS (BY INDEX ROWID) OF TEST33
INDEX (RANGE SCAN) OF TEST33_I (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF TEST32
INDEX (RANGE SCAN) OF TEST32_I (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF TEST31
INDEX (RANGE SCAN) OF TEST31_I (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF TEST30
INDEX (RANGE SCAN) OF TEST30_I (NON-UNIQUE)
뒷풀이.
이번 주제는 거의 복습하는 기분으로 부담없이 들여다 봐도
좋을 듯하다.
CREATE INDEX TEST30_I ON TEST30(KEY1);
INSERT INTO TEST30 VALUES ('A',123);
INSERT INTO TEST30 VALUES ('B',345);
INSERT INTO TEST30 VALUES ('C',357);
INSERT INTO TEST30 VALUES ('D',763);
INSERT INTO TEST30 VALUES ('E',843);
INSERT INTO TEST30 VALUES ('F',345);
INSERT INTO TEST30 VALUES ('G',235);
INSERT INTO TEST30 VALUES ('H',845);
INSERT INTO TEST30 VALUES ('I',652);
INSERT INTO TEST30 VALUES ('J',323);
CREATE TABLE TEST31 (KEY1 VARCHAR2(02),YM VARCHAR2(06), AMT1 NUMBER);
CREATE INDEX TEST31_I ON TEST31(KEY1,YM);
INSERT INTO TEST31 VALUES ('A','199905',23);
INSERT INTO TEST31 VALUES ('A','199906',43);
INSERT INTO TEST31 VALUES ('A','199907',56);
INSERT INTO TEST31 VALUES ('B','199906',23);
INSERT INTO TEST31 VALUES ('B','199907',43);
INSERT INTO TEST31 VALUES ('C','199908',56);
CREATE TABLE TEST32 (KEY1 VARCHAR2(02),YM VARCHAR2(06), AMT2 NUMBER);
CREATE INDEX TEST32_I ON TEST32(KEY1,YM);
INSERT INTO TEST32 VALUES ('B','199905',33);
INSERT INTO TEST32 VALUES ('C','199906',65);
INSERT INTO TEST32 VALUES ('D','199907',87);
INSERT INTO TEST32 VALUES ('D','199908',12);
INSERT INTO TEST32 VALUES ('E','199907',45);
INSERT INTO TEST32 VALUES ('E','199908',89);
CREATE TABLE TEST33 (KEY1 VARCHAR2(02),YM VARCHAR2(06), AMT3 NUMBER);
CREATE INDEX TEST33_I ON TEST33(KEY1,YM);
INSERT INTO TEST33 VALUES ('B','199905',76);
INSERT INTO TEST33 VALUES ('C','199906',98);
INSERT INTO TEST33 VALUES ('E','199907',21);
INSERT INTO TEST33 VALUES ('F','199908',54);
INSERT INTO TEST33 VALUES ('G','199907',87);
INSERT INTO TEST33 VALUES ('H','199908',85);
상호간 OUTER 조인의 해결방안
조건.
TEST30
열 이름 유형
--------- ----
KEY1 VARCHAR2(2)
AMT NUMBER
KEY1 AMT
---- --------
A 123
B 345
C 357
D 763
E 843
F 345
G 235
H 845
I 652
J 323
TEST31 TEST32 TEST33
열 이름 유형 열 이름 유형 열 이름 유형
--------- ---- --------- ---- --------- ----
KEY1 VARCHAR2(2) KEY1 VARCHAR2(2) KEY1 VARCHAR2(2)
YM VARCHAR2(6) YM VARCHAR2(6) YM VARCHAR2(6)
AMT1 NUMBER AMT2 NUMBER AMT3 NUMBER
KEY1 YM AMT1 KEY1 YM AMT2 KEY1 YM AMT3
---- ------ ------ ---- ------ ------ ---- ------ ------
A 199905 23 B 199905 33 B 199905 76
A 199906 43 C 199906 65 C 199906 98
A 199907 56 D 199907 87 E 199907 21
B 199906 23 D 199908 12 F 199908 54
B 199907 43 E 199907 45 G 199907 87
C 199908 56 E 199908 89 H 199908 85
문제.
TEST30의 KEY1을 FOREIGN KEY 로
TEST31부터 TEST33 까지가 KEY1과 YM을 PRIMARY KEY로 가지고 있는
다른 성격의 DATA를 관리하는 같은 구조의 테이블이다.
TEST31부터 TEST33까지에 DATAT가 존재하면 존재하는 모든 DATA를
YM과 KEY1순으로 정렬 하여
TEST30.AMT, TEST31.AMT1, TEST32.AMT2, TEST33.AMT3
을 보고싶다.
결과가 다음과 같이 나오면 되겠다.
YM KEY1 AMT AMT1 AMT2 AMT3
------ ---- ---------- ---------- ---------- ----------
199905 A 123 23
199905 B 345 33 76
199906 A 123 43
199906 B 345 23
199906 C 357 65 98
199907 A 123 56
199907 B 345 43
199907 D 763 87
199907 E 843 45 21
199907 G 235 87
199908 C 357 56
199908 D 763 12
199908 E 843 89
199908 F 345 54
199908 H 845 85
생각.
실제 설계에서는 피해가는 부분이지만 어쩔 수 없이 위와 같이
설계가 이루어지는 경우가 있다.
조건식에서 양방향 OUTER JOIN을 이용할 수 있다면 혹시 쉽게
해결할 수 있는 문제일지 모른다.
하지만 불행하게도 양방향 OUTER JOIN 은 먹혀들지를 않는다.
MASTER인 TEST30을 기준으로 OUTER 조인을 사용할 것인가?..
KEY1만 이라면 그렇게 할 수도 있을 것이다.
하지만 YM에 대해서는 또 어떻게 할 것인가?.
앞 주제중에 구조 DATA를 이용하는 주제가 있었다.
해결 방법은 그 방법과 흡사하다.
KEY1과 YM을 먼저 만들어 놓고 그것을 기준으로 OUTER 조인을
사용하면 된다.
복습하는 셈 치고 한번 직접 해보자.
결코 어려운 문제가 아니다.
해법.TEST31 부터 TESTT33 사이에 존재하는 KEY과 YM을 먼저 만들어보자.
31부터 33까지에서 KEY와 YM을 따로 읽어서 UNION 을 하게되면
두개의 KEY를 기준으로 UNIQUE한 DATA가 나온다.
SELECT YM,KEY1 FROM TEST31
UNION
SELECT YM,KEY1 FROM TEST32
UNION
SELECT YM,KEY1 FROM TEST33
YM KEY1
------ --
199905 A
199905 B
199906 A
199906 B
199906 C
199907 A
199907 B
199907 D
199907 E
199907 G
199908 C
199908 D
199908 E
199908 F
199908 H
여기까지 했으면 다했다.
이제 위의 DATASET을 기준으로 OUTER JOIN만 해 주면 된다.
SELECT A.YM,A.KEY1,B.AMT,C.AMT1,D.AMT2,E.AMT3
FROM (SELECT YM,KEY1 FROM TEST31
UNION
SELECT YM,KEY1 FROM TEST32
UNION
SELECT YM,KEY1 FROM TEST33) A,
TEST30 B,
TEST31 C,
TEST32 D,
TEST33 E
WHERE B.KEY1(+) = A.KEY1
AND C.KEY1(+) = A.KEY1
AND C.YM(+) = A.YM
AND D.KEY1(+) = A.KEY1
AND D.YM(+) = A.YM
AND E.KEY1(+) = A.KEY1
AND E.YM(+) = A.YM
결과는 문제의 답과 같다.
PLAN :
SELECT STATEMENT Optimizer=CHOOSE
NESTED LOOPS (OUTER)
NESTED LOOPS (OUTER)
NESTED LOOPS (OUTER)
NESTED LOOPS (OUTER)
VIEW
SORT (UNIQUE)
UNION-ALL
TABLE ACCESS (FULL) OF TEST31
TABLE ACCESS (FULL) OF TEST32
TABLE ACCESS (FULL) OF TEST33
TABLE ACCESS (BY INDEX ROWID) OF TEST33
INDEX (RANGE SCAN) OF TEST33_I (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF TEST32
INDEX (RANGE SCAN) OF TEST32_I (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF TEST31
INDEX (RANGE SCAN) OF TEST31_I (NON-UNIQUE)
TABLE ACCESS (BY INDEX ROWID) OF TEST30
INDEX (RANGE SCAN) OF TEST30_I (NON-UNIQUE)
뒷풀이.
이번 주제는 거의 복습하는 기분으로 부담없이 들여다 봐도
좋을 듯하다.
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
66 | 부등호 조인 | 운영자 | 2002.09.18 | 56705 |
65 | 행렬(matrix)계산을위한 준비 | 운영자 | 2002.09.18 | 3061 |
64 | 최대값과 해당해의 다른값 가져오기 | 운영자 | 2002.09.18 | 3221 |
63 | DATA 병합 | 운영자 | 2002.09.18 | 2578 |
62 | 다수 NULL 허용 COLUMN의 명칭을 가져올때 | 운영자 | 2002.09.18 | 3732 |
61 | 수식이용 | 운영자 | 2002.09.18 | 2738 |
60 | JOIN과 SUBQUERY가 동일한 예제 | 운영자 | 2002.09.18 | 2950 |
59 | NULL과 0 의 AVG 차이 비교 | 운영자 | 2002.09.18 | 2875 |
58 | 고정된 Row 수 유지 | 운영자 | 2002.09.18 | 4228 |
57 | 두개 RECORD를 한행에 DISPLAY 시키기 | 운영자 | 2002.09.18 | 3162 |
56 | LENGTH/LENGTHB,SUBSTR/SUBSTRB,INSTR/INSTRB | 운영자 | 2002.09.18 | 4292 |
55 | 한줄에 2 ROW 보여주기 변형II | 운영자 | 2002.09.18 | 3109 |
» | 상호간 OUTER 조인의 해결방안 | 운영자 | 2002.09.18 | 2941 |
53 | 선택적조인 | 운영자 | 2002.09.18 | 2961 |
52 | 반올림 DATA의 오차보정 | 운영자 | 2002.09.18 | 3585 |
51 | 복제를이용한 합계계에서 비율계산 | 운영자 | 2002.09.18 | 3669 |
50 | DATA변환 | 운영자 | 2002.09.18 | 2750 |
49 | 중간값구하기 | 운영자 | 2002.09.18 | 3377 |
48 | 한번 읽은 테이블로 백분율 구하기 | 운영자 | 2002.09.18 | 4085 |
47 | 빠진이빨찾기 III | 운영자 | 2002.09.18 | 3359 |