CREATE TABLE SAM_TAB02 (구분 VARCHAR2(5) );
DECLARE
SU NUMBER;
BEGIN
SU:=106;
LOOP
SU:=SU+1;
EXIT WHEN SU>125;
INSERT INTO SAM_TAB02
VALUES('F'||TO_CHAR(SU));
END LOOP;
END;
RECORD 단위 DATA 를 COLUMN 단위로
조건
개발자는 고객의 요구를 자~알 만족시켜줘야한다.
하지만 우리의 유저는 머리속에서만 구현가능하면 당연히 컴퓨터도
할 수 있다고 생각하고 그것을 요구한다.
그럼 어쩌나?...해줘야지..
1. 우리가 흔히 DATA를 다룰때 RECORD 단위로 뿌려지는 DATA를
COLUMN 단위로 보아야 할 경우가 있다.
2. 레코드가 몇개가 나올지 모르는 DATA를 끝도없이 옆으로
늘려간다는것도 불가능하니 주어지는 단위만큼 보여주고
다시 다음 줄에보여주고 하는식의 QUERY를 구현하고자 한다.
3. 쉽게 얘기해서
SAM_TAB2 의 여러 COLUMN 중 "구분" 이라는 COLUMN 에
다음과 같은 DATA가 들어있다.
구분
----
F106
F107
F108
F109
F110
F111
F112
F113
F114
F115
F116
F117
F118
F119
F120
F121
F122
F123
F124
F125
위와같이 QUERY 되어 나오는 DATA를
순서 COL1 COL1 COL1 COL1
---- ---- ---- ---- ----
01 F106 F107 F108 F109
02 F110 F111 F112 F113
03 F114 F115 F116 F117
04 F118 F119 F120 F121
05 F122 F123 F124 F125
이렇게 보고싶다는 이야긴데...
문제 .
조건에서 문제를 얘기해버렸네..
그래도 문제는 있어야지!.
자~알 보여주세요.
생각 .
문제에 부딪히면 누구나 생각을 먼저 하게 된다.
결과가 좋은지 나쁜지는 다음문제지만..
어쨋든 생각을 해보자
엿보기1. 모든 QUERY 에는 ROWNUM이라는 놈이 함께 달려나온다.
각 RECORD 마다에 번호표를 붙여줄 수 있다는 얘기다.
2. 그럼 더이상 엿볼게 없다.
붙여진 번호표를 각번호마다 불러서
몇번은 몇번째줄 몇번째칸에 가서 서라....라고 명령만하면
자기가 자기집을 찾아가서 서버리기 때문이다.
3. 우리가 할일은 더이상 없다.
해법 .
생각하다보니 해법이 다 나왔다.
말만 바꿔주면된다.
단계1. 제일먼저 각 RECORD마다 번호표를 붙여준다.
SELECT ROWNUM CNT,TYPE_CD
FROM HDAT_TYPE_CD
단계2. 위에서 읽혀온 DATASET 을 이용해 다음에 할일은
각번호를 몇번째 ROW 몇번째 COLUMN 에 세울건지를
결정해줘야한다.
답이 이미 4개단위로 되어있으니 한ROW에 보여주는
RECORD 는 4개로 결정짓자.
결국
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
과 같은 식으로 DATA의 배열이 이루어지면된다.
먼저 ROW를 생각하면
4개의 RECORD가 같은 ROW번호표를 갖고
같은 줄의 각각의 DATA가 순서대로 1번부터 4번까지를 나눠
가지면 된다.
ROW COL DATA
--- --- ----
1 1 1
1 2 2
1 3 3
1 4 4
2 1 5
2 2 6
2 3 7
2 4 8
3 1 9
3 2 10
3 3 11
3 4 12
4 1 13
4 2 14
4 3 15
4 4 16
5 1 17
5 2 18
5 3 19
5 4 20
즉 위와 같은식으로 되면된다.
이렇게 써주면 된다.
SELECT CEIL(CNT/4) ROW_CNT,
DECODE(MOD(CNT,4),0,4,MOD(CNT,4)),
구분
FROM
(SELECT ROWNUM CNT,구분
FROM SAM_TAB2
)
단계3.이제 배열만 하면 된다.
SELECT CEIL(CNT/4) ROW_CNT,
MAX(DECODE(MOD(CNT,4),1,구분)),
MAX(DECODE(MOD(CNT,4),2,구분)),
MAX(DECODE(MOD(CNT,4),3,구분)),
MAX(DECODE(MOD(CNT,4),0,구분))
FROM
(SELECT ROWNUM CNT,구분
FROM SAM_TAB2
)
GROUP BY CEIL(CNT/4)
이것이 답이다.
PLAN
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 VIEW
3 2 COUNT
4 3 TABLE ACCESS (FULL) OF 'SAM_TAB2'
뒷풀이 .
단계3 에서 해준일은 ROW_CNT 를 Grouping 단위로 하여
Column Count 에 따라 위치를 정해주고 그값이 존재하는
Column만으로 Data를 압축시킨경우이다.
우리가 흔히 사용하는 SUM(DECODE()) 와 같은 경우다.
그래도 이해가 안되시는 분들을 위해 잠간 그림을 그려보면
SELECT CEIL(CNT/4) ROW_CNT,
DECODE(MOD(CNT,4),1,구분),
DECODE(MOD(CNT,4),2,구분),
DECODE(MOD(CNT,4),3,구분),
DECODE(MOD(CNT,4),0,구분)
FROM
(SELECT ROWNUM CNT,구분
FROM SAM_TAB2
)
그룹지어주지 않은 자료이다.
ROW_CNT COL1 COL2 COL3 COL4
------- ---- ---- ---- ----
1 F106
1 F107
1 F108
1 F109
2 F110
2 F111
2 F112
2 F113
3 F114
3 F115
3 F116
3 F117
4 F118
4 F119
4 F120
4 F121
5 F122
5 F123
5 F124
5 F125
이 자료를 ROW_CNT로 그룹지어
각 COLUMN의 최대값을 가져오면
순서 COL1 COL1 COL1 COL1
---- ---- ---- ---- ----
01 F106 F107 F108 F109
02 F110 F111 F112 F113
03 F114 F115 F116 F117
04 F118 F119 F120 F121
05 F122 F123 F124 F125
이렇게 답이되는 것이다.
사족 .
단점이라면 몇COLUMN을 한 ROW에 볼것인가 하는 문제를 미리
결정해줘야 한다는 것이다.
경우에 따라 한줄에 몇 COLUMN 이 올지 모르는 경우라면
그 최대 COLUMN 수를 MAX(DECODE())로 만들어 놓고 PARAMETER값의
변동에 따라 계산을 해줄 수 있다.
DECLARE
SU NUMBER;
BEGIN
SU:=106;
LOOP
SU:=SU+1;
EXIT WHEN SU>125;
INSERT INTO SAM_TAB02
VALUES('F'||TO_CHAR(SU));
END LOOP;
END;
RECORD 단위 DATA 를 COLUMN 단위로
조건
개발자는 고객의 요구를 자~알 만족시켜줘야한다.
하지만 우리의 유저는 머리속에서만 구현가능하면 당연히 컴퓨터도
할 수 있다고 생각하고 그것을 요구한다.
그럼 어쩌나?...해줘야지..
1. 우리가 흔히 DATA를 다룰때 RECORD 단위로 뿌려지는 DATA를
COLUMN 단위로 보아야 할 경우가 있다.
2. 레코드가 몇개가 나올지 모르는 DATA를 끝도없이 옆으로
늘려간다는것도 불가능하니 주어지는 단위만큼 보여주고
다시 다음 줄에보여주고 하는식의 QUERY를 구현하고자 한다.
3. 쉽게 얘기해서
SAM_TAB2 의 여러 COLUMN 중 "구분" 이라는 COLUMN 에
다음과 같은 DATA가 들어있다.
구분
----
F106
F107
F108
F109
F110
F111
F112
F113
F114
F115
F116
F117
F118
F119
F120
F121
F122
F123
F124
F125
위와같이 QUERY 되어 나오는 DATA를
순서 COL1 COL1 COL1 COL1
---- ---- ---- ---- ----
01 F106 F107 F108 F109
02 F110 F111 F112 F113
03 F114 F115 F116 F117
04 F118 F119 F120 F121
05 F122 F123 F124 F125
이렇게 보고싶다는 이야긴데...
문제 .
조건에서 문제를 얘기해버렸네..
그래도 문제는 있어야지!.
자~알 보여주세요.
생각 .
문제에 부딪히면 누구나 생각을 먼저 하게 된다.
결과가 좋은지 나쁜지는 다음문제지만..
어쨋든 생각을 해보자
엿보기1. 모든 QUERY 에는 ROWNUM이라는 놈이 함께 달려나온다.
각 RECORD 마다에 번호표를 붙여줄 수 있다는 얘기다.
2. 그럼 더이상 엿볼게 없다.
붙여진 번호표를 각번호마다 불러서
몇번은 몇번째줄 몇번째칸에 가서 서라....라고 명령만하면
자기가 자기집을 찾아가서 서버리기 때문이다.
3. 우리가 할일은 더이상 없다.
해법 .
생각하다보니 해법이 다 나왔다.
말만 바꿔주면된다.
단계1. 제일먼저 각 RECORD마다 번호표를 붙여준다.
SELECT ROWNUM CNT,TYPE_CD
FROM HDAT_TYPE_CD
단계2. 위에서 읽혀온 DATASET 을 이용해 다음에 할일은
각번호를 몇번째 ROW 몇번째 COLUMN 에 세울건지를
결정해줘야한다.
답이 이미 4개단위로 되어있으니 한ROW에 보여주는
RECORD 는 4개로 결정짓자.
결국
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
과 같은 식으로 DATA의 배열이 이루어지면된다.
먼저 ROW를 생각하면
4개의 RECORD가 같은 ROW번호표를 갖고
같은 줄의 각각의 DATA가 순서대로 1번부터 4번까지를 나눠
가지면 된다.
ROW COL DATA
--- --- ----
1 1 1
1 2 2
1 3 3
1 4 4
2 1 5
2 2 6
2 3 7
2 4 8
3 1 9
3 2 10
3 3 11
3 4 12
4 1 13
4 2 14
4 3 15
4 4 16
5 1 17
5 2 18
5 3 19
5 4 20
즉 위와 같은식으로 되면된다.
이렇게 써주면 된다.
SELECT CEIL(CNT/4) ROW_CNT,
DECODE(MOD(CNT,4),0,4,MOD(CNT,4)),
구분
FROM
(SELECT ROWNUM CNT,구분
FROM SAM_TAB2
)
단계3.이제 배열만 하면 된다.
SELECT CEIL(CNT/4) ROW_CNT,
MAX(DECODE(MOD(CNT,4),1,구분)),
MAX(DECODE(MOD(CNT,4),2,구분)),
MAX(DECODE(MOD(CNT,4),3,구분)),
MAX(DECODE(MOD(CNT,4),0,구분))
FROM
(SELECT ROWNUM CNT,구분
FROM SAM_TAB2
)
GROUP BY CEIL(CNT/4)
이것이 답이다.
PLAN
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 VIEW
3 2 COUNT
4 3 TABLE ACCESS (FULL) OF 'SAM_TAB2'
뒷풀이 .
단계3 에서 해준일은 ROW_CNT 를 Grouping 단위로 하여
Column Count 에 따라 위치를 정해주고 그값이 존재하는
Column만으로 Data를 압축시킨경우이다.
우리가 흔히 사용하는 SUM(DECODE()) 와 같은 경우다.
그래도 이해가 안되시는 분들을 위해 잠간 그림을 그려보면
SELECT CEIL(CNT/4) ROW_CNT,
DECODE(MOD(CNT,4),1,구분),
DECODE(MOD(CNT,4),2,구분),
DECODE(MOD(CNT,4),3,구분),
DECODE(MOD(CNT,4),0,구분)
FROM
(SELECT ROWNUM CNT,구분
FROM SAM_TAB2
)
그룹지어주지 않은 자료이다.
ROW_CNT COL1 COL2 COL3 COL4
------- ---- ---- ---- ----
1 F106
1 F107
1 F108
1 F109
2 F110
2 F111
2 F112
2 F113
3 F114
3 F115
3 F116
3 F117
4 F118
4 F119
4 F120
4 F121
5 F122
5 F123
5 F124
5 F125
이 자료를 ROW_CNT로 그룹지어
각 COLUMN의 최대값을 가져오면
순서 COL1 COL1 COL1 COL1
---- ---- ---- ---- ----
01 F106 F107 F108 F109
02 F110 F111 F112 F113
03 F114 F115 F116 F117
04 F118 F119 F120 F121
05 F122 F123 F124 F125
이렇게 답이되는 것이다.
사족 .
단점이라면 몇COLUMN을 한 ROW에 볼것인가 하는 문제를 미리
결정해줘야 한다는 것이다.
경우에 따라 한줄에 몇 COLUMN 이 올지 모르는 경우라면
그 최대 COLUMN 수를 MAX(DECODE())로 만들어 놓고 PARAMETER값의
변동에 따라 계산을 해줄 수 있다.