고정된 Row 수 유지
조건.
ORACLE SCOTT USER 에 LOGIN 하면 DEPT 라는 TABLE이 있다.
SCOTT USER의 DEPT는 다음과 같다.
열 이름 널? 유형
------------------------------ -------- ----
DEPTNO NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
문제.
질문내용:
"select * from dept where dept_code=12
에서 select 된 row의 갯수가 3개이면 7개 row의 값이 null 값으로
채워지고
select 된 row의 갯수가 4개이면 6개 row의 값이 null 값으로 채워져
select된 row의 수는 항상 10개를 유지 합니다.
이런 select문이 가능한지요.."
아마 DEPT TABLE 이 SCOTT USER 에서 제공되는 TABLE 이 아닌
직접 CREATE 시킨 TABLE인듯 하다.
DEPT_CODE = 12 라는 조건이 들어 있는 것으로 봐서 짐 작할 수 있다.
생각.
위의 질문을 만족하기 위해서는 항상 조건식에 의해 DEPT TABLE에서
읽혀오는 DATA의 건수가 10개보다 작아야 의미가 있을 것이다.
10개를 넘는다 해도 문제 될것은 없지만 10개의 RECORD로
고정 시키다 보면 11번째 DATA부터는 결과에 포함되어 나오지 않기
때문이다.
어떤 양식을 맞추거나 약간의 편법을 이용해 다른 문제를 뚫고
나가기위해 필요하지 않았는가 싶다.
어쨋든 위의 문제에 대한 해답을 구하고 어느 경우에 쓰일 수
있는지도 생각해 보자.
우리가 사용할 DEPT TABLE은 조건에 나타나 있는 TABLE이다.
결과가 아래와 같이 나오면 될듯 하다.
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
10 행이 선택되었습니다.
DEPT TABLE에서 결과를 만족하는 DATA가 몇개이든 간에
"10 행이 선택되었습니다." 라는 메세지가 떠야 한다.
해법.
쉽게 생각하면 쉬운 문제다.
우리는 이미 OUTER JOIN에 대하여 알고 있다.
어떤 테이블이 있다고 가정하자.
DEPT TABLE 과 1:1 조인을 걸수있는 TABLE 이고
그 테이블에서는 항상 DEPT에서 추출된 결과를 포함하는 10개의 RECORD를
RETURN 할 수 있으면 DEPT와 그 테이블을 EQUAL JOIN 으로 연결하되
DEPT 에 OUTER 조인이 되도록 연결하면 된다.
예를 들어 보자.
다음과 같은 구조와 DATA를 가진 TEST27 이라는 TABLE이 있다.
그렇다면 간단할 것이다.
DEPTNO
----------
10
20
30
40
50
60
70
80
90
100
10 행이 선택되었습니다
두 TABLE을 OUTER JOIN으로 연결만 하면 될테니까..
연결해보자.
SELECT A.DEPTNO,DNAME,LOC
FROM DEPT A,
TEST27 B
WHERE A.DEPTNO(+) = B.DEPTNO
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
10 행이 선택되었습니다
와 같은 결과가 나온다.
그런데 몇가지 문제가 있다.
첫번째 QUERY 하나를 위해 TABLE을 새로 만들어야 하며
두번째 부서 TABLE에 조건이 걸리면 TEST27에도 같은 조건을
걸어줘야하고, 그것을 포함해 10개가 될수 있도록 QUERY를
구성해 줘야한다
그래서 항상 TEST27에는 10개 이상의 RECORD가
TEST27에 있는 DEPTNO를 모두 포함하면서 존재해야한다.
이유는 DEPT TABLE에 현재처럼 DATA가 4개밖에 없으면
DEPT 하나의 TABLE만으로는 해결이 곤란하기 때문이다.
세번째 DEPT TABLE에 변경이 일어날때마다 TEST26 도 함께
고려해야 한다는 것이다.
QUERY하나를 성공시키기 위해 너무 많은 희생을 치뤄야 한다.
세가지 문제가 발생하는 근본적인 원인은 우리가 1:1 조인의
연결고리를 DEPTNO로 잡았기 때문이다.
그렇다면 연결고리를 바꿀 방법은 없는가?.
연결고리를 항상 일정하게 변하지 않는 것으로 잡는다면
어떤 DEPTNO 가 결과에 끌려오더라도 문제가 없을듯한데...
제일먼저 무엇이 떠오르는가?.
문제에서 요구하는 것이 10 건의 RECORD를 유지시켜 달라는
것이었다.
DEPT의 1번 RECORD가 그 어떤 TABLE의 1번과 2번이 2번과
.....10번이 있다면
10번과 10번이 연결되고 10번을 포함한 그이하가 DEPT에 없더라도
OUTER JOIN으로 10번과 연결하면 항상 10개의 RECORD가
나올 것이다.
이제 문제의 핵심이 좁혀졌다.
DEPT 와 JOIN을 걸어줄 어떤 TABLE에서 읽혀오는 두개의 DATASET에
번호표를 붙여주고 같은 번호끼리 연결을 해보자.
그 어떤 TABLE은 단지 무작정 10개의 번호만 제공하면된다.
그 이상은 필요가 없다.
10개의 번호를 제공할 수 있는 TABLE은 10개 이상의 RECORD가
존재하는 TABLE이면 된다.
반드시 TABLE이 아닌 VIEW라도 좋다.
여기서는 USER_TABLES를 이용하자.
다음과 같은 QUERY를 만들면
select rownum r_cnt from user_tables where rownum < 11
아래와 같은 결과가 나오리라.
R_CNT
----------
1
2
3
4
5
6
7
8
9
10
10 행이 선택되었습니다
이번에는 DEPT TABLE에 번호표를 달아서 읽어보자.
select rownum r_cnt,deptno,dname,loc from dept
R_CNT DEPTNO DNAME LOC
---------- ---------- -------------- -------------
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON
이제 두 DATASET을 OUTER JOIN으로 연결하자.
select deptno,dname,loc
from (select rownum r_cnt,deptno,dname,loc
from dept ) a,
(select rownum r_cnt from user_tables
where rownum < 11) b
where a.r_cnt(+) = b.r_cnt
결과는 문제의 답과 동일하다.
뒷풀이.
언제 쓰일 수있는 QUERY 인가.
전혀 상관관계가 없는 두개의 DATASET을 1:1로 조인 하고자 할때
유용할 것이다.
흔히 상관없는 DATA가 JOIN이 걸리면 연결고리가 없으므로 M:N 으로
CARTESIAN PRODDUCT가 일어나는 것이 일반 적이다.
어떤 이유로해서 두개의 연결고리가 필요할때 유용하게 쓰일 수
있는 방법이다.
살며시 기억해 두자.
조건.
ORACLE SCOTT USER 에 LOGIN 하면 DEPT 라는 TABLE이 있다.
SCOTT USER의 DEPT는 다음과 같다.
열 이름 널? 유형
------------------------------ -------- ----
DEPTNO NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
문제.
질문내용:
"select * from dept where dept_code=12
에서 select 된 row의 갯수가 3개이면 7개 row의 값이 null 값으로
채워지고
select 된 row의 갯수가 4개이면 6개 row의 값이 null 값으로 채워져
select된 row의 수는 항상 10개를 유지 합니다.
이런 select문이 가능한지요.."
아마 DEPT TABLE 이 SCOTT USER 에서 제공되는 TABLE 이 아닌
직접 CREATE 시킨 TABLE인듯 하다.
DEPT_CODE = 12 라는 조건이 들어 있는 것으로 봐서 짐 작할 수 있다.
생각.
위의 질문을 만족하기 위해서는 항상 조건식에 의해 DEPT TABLE에서
읽혀오는 DATA의 건수가 10개보다 작아야 의미가 있을 것이다.
10개를 넘는다 해도 문제 될것은 없지만 10개의 RECORD로
고정 시키다 보면 11번째 DATA부터는 결과에 포함되어 나오지 않기
때문이다.
어떤 양식을 맞추거나 약간의 편법을 이용해 다른 문제를 뚫고
나가기위해 필요하지 않았는가 싶다.
어쨋든 위의 문제에 대한 해답을 구하고 어느 경우에 쓰일 수
있는지도 생각해 보자.
우리가 사용할 DEPT TABLE은 조건에 나타나 있는 TABLE이다.
결과가 아래와 같이 나오면 될듯 하다.
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
10 행이 선택되었습니다.
DEPT TABLE에서 결과를 만족하는 DATA가 몇개이든 간에
"10 행이 선택되었습니다." 라는 메세지가 떠야 한다.
해법.
쉽게 생각하면 쉬운 문제다.
우리는 이미 OUTER JOIN에 대하여 알고 있다.
어떤 테이블이 있다고 가정하자.
DEPT TABLE 과 1:1 조인을 걸수있는 TABLE 이고
그 테이블에서는 항상 DEPT에서 추출된 결과를 포함하는 10개의 RECORD를
RETURN 할 수 있으면 DEPT와 그 테이블을 EQUAL JOIN 으로 연결하되
DEPT 에 OUTER 조인이 되도록 연결하면 된다.
예를 들어 보자.
다음과 같은 구조와 DATA를 가진 TEST27 이라는 TABLE이 있다.
그렇다면 간단할 것이다.
DEPTNO
----------
10
20
30
40
50
60
70
80
90
100
10 행이 선택되었습니다
두 TABLE을 OUTER JOIN으로 연결만 하면 될테니까..
연결해보자.
SELECT A.DEPTNO,DNAME,LOC
FROM DEPT A,
TEST27 B
WHERE A.DEPTNO(+) = B.DEPTNO
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
10 행이 선택되었습니다
와 같은 결과가 나온다.
그런데 몇가지 문제가 있다.
첫번째 QUERY 하나를 위해 TABLE을 새로 만들어야 하며
두번째 부서 TABLE에 조건이 걸리면 TEST27에도 같은 조건을
걸어줘야하고, 그것을 포함해 10개가 될수 있도록 QUERY를
구성해 줘야한다
그래서 항상 TEST27에는 10개 이상의 RECORD가
TEST27에 있는 DEPTNO를 모두 포함하면서 존재해야한다.
이유는 DEPT TABLE에 현재처럼 DATA가 4개밖에 없으면
DEPT 하나의 TABLE만으로는 해결이 곤란하기 때문이다.
세번째 DEPT TABLE에 변경이 일어날때마다 TEST26 도 함께
고려해야 한다는 것이다.
QUERY하나를 성공시키기 위해 너무 많은 희생을 치뤄야 한다.
세가지 문제가 발생하는 근본적인 원인은 우리가 1:1 조인의
연결고리를 DEPTNO로 잡았기 때문이다.
그렇다면 연결고리를 바꿀 방법은 없는가?.
연결고리를 항상 일정하게 변하지 않는 것으로 잡는다면
어떤 DEPTNO 가 결과에 끌려오더라도 문제가 없을듯한데...
제일먼저 무엇이 떠오르는가?.
문제에서 요구하는 것이 10 건의 RECORD를 유지시켜 달라는
것이었다.
DEPT의 1번 RECORD가 그 어떤 TABLE의 1번과 2번이 2번과
.....10번이 있다면
10번과 10번이 연결되고 10번을 포함한 그이하가 DEPT에 없더라도
OUTER JOIN으로 10번과 연결하면 항상 10개의 RECORD가
나올 것이다.
이제 문제의 핵심이 좁혀졌다.
DEPT 와 JOIN을 걸어줄 어떤 TABLE에서 읽혀오는 두개의 DATASET에
번호표를 붙여주고 같은 번호끼리 연결을 해보자.
그 어떤 TABLE은 단지 무작정 10개의 번호만 제공하면된다.
그 이상은 필요가 없다.
10개의 번호를 제공할 수 있는 TABLE은 10개 이상의 RECORD가
존재하는 TABLE이면 된다.
반드시 TABLE이 아닌 VIEW라도 좋다.
여기서는 USER_TABLES를 이용하자.
다음과 같은 QUERY를 만들면
select rownum r_cnt from user_tables where rownum < 11
아래와 같은 결과가 나오리라.
R_CNT
----------
1
2
3
4
5
6
7
8
9
10
10 행이 선택되었습니다
이번에는 DEPT TABLE에 번호표를 달아서 읽어보자.
select rownum r_cnt,deptno,dname,loc from dept
R_CNT DEPTNO DNAME LOC
---------- ---------- -------------- -------------
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON
이제 두 DATASET을 OUTER JOIN으로 연결하자.
select deptno,dname,loc
from (select rownum r_cnt,deptno,dname,loc
from dept ) a,
(select rownum r_cnt from user_tables
where rownum < 11) b
where a.r_cnt(+) = b.r_cnt
결과는 문제의 답과 동일하다.
뒷풀이.
언제 쓰일 수있는 QUERY 인가.
전혀 상관관계가 없는 두개의 DATASET을 1:1로 조인 하고자 할때
유용할 것이다.
흔히 상관없는 DATA가 JOIN이 걸리면 연결고리가 없으므로 M:N 으로
CARTESIAN PRODDUCT가 일어나는 것이 일반 적이다.
어떤 이유로해서 두개의 연결고리가 필요할때 유용하게 쓰일 수
있는 방법이다.
살며시 기억해 두자.
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
54 | 소계/합계 함께 보기 | 운영자 | 2002.09.18 | 3134 |
53 | 석차구하기 | 운영자 | 2002.09.18 | 2960 |
52 | COLUMN을 ROW로 | 운영자 | 2002.09.18 | 6135 |
51 | 최대값과 최소값을 뺀 평균 | 운영자 | 2002.09.18 | 4177 |
50 | 누계를 구하는 또한가지 방법 | 운영자 | 2002.09.18 | 3209 |
49 | 그룹 단위별 일련번호 붙이기 | 운영자 | 2002.09.18 | 5754 |
48 | 부등호 조인 | 운영자 | 2002.09.18 | 56705 |
47 | 행렬(matrix)계산을위한 준비 | 운영자 | 2002.09.18 | 3061 |
46 | 최대값과 해당해의 다른값 가져오기 | 운영자 | 2002.09.18 | 3221 |
45 | DATA 병합 | 운영자 | 2002.09.18 | 2578 |
44 | 다수 NULL 허용 COLUMN의 명칭을 가져올때 | 운영자 | 2002.09.18 | 3732 |
43 | 수식이용 | 운영자 | 2002.09.18 | 2738 |
42 | JOIN과 SUBQUERY가 동일한 예제 | 운영자 | 2002.09.18 | 2950 |
41 | NULL과 0 의 AVG 차이 비교 | 운영자 | 2002.09.18 | 2875 |
» | 고정된 Row 수 유지 | 운영자 | 2002.09.18 | 4228 |
39 | 두개 RECORD를 한행에 DISPLAY 시키기 | 운영자 | 2002.09.18 | 3162 |
38 | LENGTH/LENGTHB,SUBSTR/SUBSTRB,INSTR/INSTRB | 운영자 | 2002.09.18 | 4292 |
37 | 한줄에 2 ROW 보여주기 변형II | 운영자 | 2002.09.18 | 3109 |
36 | 상호간 OUTER 조인의 해결방안 | 운영자 | 2002.09.18 | 2941 |
35 | 선택적조인 | 운영자 | 2002.09.18 | 2961 |