CREATE TABLE TEST34(KEY1 VARCHAR2(03),KEY_TYPE VARCHAR2(01),AMT NUMBER);
CREATE UNIQUE INDEX TEST34_I ON TEST34(KEY1);
INSERT INTO TEST34 VALUES ('A01','1',10);
INSERT INTO TEST34 VALUES ('A02','2',20);
INSERT INTO TEST34 VALUES ('A03','1',30);
INSERT INTO TEST34 VALUES ('A04','2',40);
INSERT INTO TEST34 VALUES ('A05','3',50);
INSERT INTO TEST34 VALUES ('A06','3',60);
INSERT INTO TEST34 VALUES ('A07','1',70);
INSERT INTO TEST34 VALUES ('A08','2',80);
INSERT INTO TEST34 VALUES ('A09','1',90);
선택적 조인
조건.
TEST34 에 다음과 같은 DATA가 있다.
KEY1 KEY_TYPE AMT
---- -------- ----------
A01 1 10
A02 2 20
A03 1 30
A04 2 40
A05 3 50
A06 3 60
A07 1 70
A08 2 80
A09 1 90
문제.
KEY_TYPE 이 '1','2','3' 3종류로 분류되어있다.
위의 분류를 A,B 두 분류로 나누어 조회하기를 원한다.
KEY_TYPE 에 따라
'1' 인 경우는 'A'에 더해지고
'2' 인 경우는 'B'에 더해지며
'3' 인 경우는 'A','B' 모두에 더해진다.
따라서 결과에서 나온 총 합은 위의 DATA 총합보다 많은데
KEY_TYPE 이 '3' 인경우의 합만큼 많게 된다.
결과가 아래와 같이 나오면 된다.
TYPE AMT
---- ----------
A 310
B 250
A 는 KEY_TYPE '1'과 '3' 의 SUM 이고
B 는 KEY_TYPE '2'와 '3' 의 SUM 이다.
단 PLAN 상으로 TEST34에대한 ACCESS 는 한번만 일어나도록
하여야 한다.
생각.
가장쉬운 해결책은 무엇이겠는가?.
우리가 흔히 사용하는 방법이며 가장 일반적인 방법으로
UNION 을 이용하는 방법이 있을 것이다.
A를 위한 SELECT 와 B를 위한 SELECT 를 따로 만들어서
두 DATASET을 UNION ALL 하면 원하는 결과가 나올 것이다.
SELECT 'A' TYPE,
SUM(AMT) AMT
FROM TEST34
WHERE KEY_TYPE IN ('1','3')
UNION ALL
SELECT 'B',SUM(AMT)
FROM TEST34
WHERE KEY_TYPE IN ('2','3')
.KEY_TYPE 이라는 조건이 오면 항상
왼쪽 조건과 같아지게 된다.
그대로 옮겨보자.
WHERE T1.KEY_TYPE
= DECODE(T1.KEY_TYPE,3,T1.KEY_TYPE,T2.R_CNT)
단계5.최종 문장을 보자.
SELECT DECODE(T2.R_CNT,1,'A',2,'B') TYPE,
SUM(AMT) AMT
FROM TEST34 T1,
(SELECT ROWNUM R_CNT FROM TEST34
WHERE ROWNUM < 3) T2
WHERE T1.KEY_TYPE
= DECODE(T1.KEY_TYPE,3,T1.KEY_TYPE,T2.R_CNT)
GROUP BY
DECODE(T2.R_CNT,1,'A',2,'B')
PLAN :
SELECT STATEMENT Optimizer=CHOOSE
SORT (GROUP BY)
NESTED LOOPS
VIEW
COUNT (STOPKEY)
TABLE ACCESS (FULL) OF TEST34
TABLE ACCESS (FULL) OF TEST34
한가지 아쉬운점이 있다면 INDEX COLUMN인 KEY_TYPE 에 DECODE로
가공이 들어감으로 인해 INDEX SCAN을 하지 못한다는 것이다.
뒷풀이.
결과는 문제에서 요구한 답과 같다.
단지 UNION으로 해결하면 될 문제를 왜 이렇게 어렵게 끌고
가느냐고 묻고 싶을지도 모르겠다.
운이 좋은 경우기 때문에 UNION으로도 풀리는 것이지,
항상 그런것은 아니다.
지금은 2개의 QUERY만 UNION으로 엮어 해결이 될 수 있지만,
상황에 따라 그것이 몇개로 늘어날지 모른다.
그것을 조건절을 잘 조절해 해결할 수 있다면 어느 방법이
나은가?.
스스로 판단해보자.
CREATE UNIQUE INDEX TEST34_I ON TEST34(KEY1);
INSERT INTO TEST34 VALUES ('A01','1',10);
INSERT INTO TEST34 VALUES ('A02','2',20);
INSERT INTO TEST34 VALUES ('A03','1',30);
INSERT INTO TEST34 VALUES ('A04','2',40);
INSERT INTO TEST34 VALUES ('A05','3',50);
INSERT INTO TEST34 VALUES ('A06','3',60);
INSERT INTO TEST34 VALUES ('A07','1',70);
INSERT INTO TEST34 VALUES ('A08','2',80);
INSERT INTO TEST34 VALUES ('A09','1',90);
선택적 조인
조건.
TEST34 에 다음과 같은 DATA가 있다.
KEY1 KEY_TYPE AMT
---- -------- ----------
A01 1 10
A02 2 20
A03 1 30
A04 2 40
A05 3 50
A06 3 60
A07 1 70
A08 2 80
A09 1 90
문제.
KEY_TYPE 이 '1','2','3' 3종류로 분류되어있다.
위의 분류를 A,B 두 분류로 나누어 조회하기를 원한다.
KEY_TYPE 에 따라
'1' 인 경우는 'A'에 더해지고
'2' 인 경우는 'B'에 더해지며
'3' 인 경우는 'A','B' 모두에 더해진다.
따라서 결과에서 나온 총 합은 위의 DATA 총합보다 많은데
KEY_TYPE 이 '3' 인경우의 합만큼 많게 된다.
결과가 아래와 같이 나오면 된다.
TYPE AMT
---- ----------
A 310
B 250
A 는 KEY_TYPE '1'과 '3' 의 SUM 이고
B 는 KEY_TYPE '2'와 '3' 의 SUM 이다.
단 PLAN 상으로 TEST34에대한 ACCESS 는 한번만 일어나도록
하여야 한다.
생각.
가장쉬운 해결책은 무엇이겠는가?.
우리가 흔히 사용하는 방법이며 가장 일반적인 방법으로
UNION 을 이용하는 방법이 있을 것이다.
A를 위한 SELECT 와 B를 위한 SELECT 를 따로 만들어서
두 DATASET을 UNION ALL 하면 원하는 결과가 나올 것이다.
SELECT 'A' TYPE,
SUM(AMT) AMT
FROM TEST34
WHERE KEY_TYPE IN ('1','3')
UNION ALL
SELECT 'B',SUM(AMT)
FROM TEST34
WHERE KEY_TYPE IN ('2','3')
.KEY_TYPE 이라는 조건이 오면 항상
왼쪽 조건과 같아지게 된다.
그대로 옮겨보자.
WHERE T1.KEY_TYPE
= DECODE(T1.KEY_TYPE,3,T1.KEY_TYPE,T2.R_CNT)
단계5.최종 문장을 보자.
SELECT DECODE(T2.R_CNT,1,'A',2,'B') TYPE,
SUM(AMT) AMT
FROM TEST34 T1,
(SELECT ROWNUM R_CNT FROM TEST34
WHERE ROWNUM < 3) T2
WHERE T1.KEY_TYPE
= DECODE(T1.KEY_TYPE,3,T1.KEY_TYPE,T2.R_CNT)
GROUP BY
DECODE(T2.R_CNT,1,'A',2,'B')
PLAN :
SELECT STATEMENT Optimizer=CHOOSE
SORT (GROUP BY)
NESTED LOOPS
VIEW
COUNT (STOPKEY)
TABLE ACCESS (FULL) OF TEST34
TABLE ACCESS (FULL) OF TEST34
한가지 아쉬운점이 있다면 INDEX COLUMN인 KEY_TYPE 에 DECODE로
가공이 들어감으로 인해 INDEX SCAN을 하지 못한다는 것이다.
뒷풀이.
결과는 문제에서 요구한 답과 같다.
단지 UNION으로 해결하면 될 문제를 왜 이렇게 어렵게 끌고
가느냐고 묻고 싶을지도 모르겠다.
운이 좋은 경우기 때문에 UNION으로도 풀리는 것이지,
항상 그런것은 아니다.
지금은 2개의 QUERY만 UNION으로 엮어 해결이 될 수 있지만,
상황에 따라 그것이 몇개로 늘어날지 모른다.
그것을 조건절을 잘 조절해 해결할 수 있다면 어느 방법이
나은가?.
스스로 판단해보자.
댓글 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 |
54 | 상호간 OUTER 조인의 해결방안 | 운영자 | 2002.09.18 | 2941 |
» | 선택적조인 | 운영자 | 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 |