result_table column
CLOSE_DATE VARCHAR2(8)
RESULT_KIND VARCHAR2(2)
RESULT_EMP VARCHAR2(7)
RESULT_AMT NUMBER(15)
실적마감 테이블 result_table에는 매주 토요일 실적이 집계됩니다.
사원은 그주에 실적이 있을 수도 없을 수도 있어서
SELECT dum_days, a.result_emp, accu_sum
FROM
( SELECT close_date, result_emp
, SUM(result_amt) over (PARTITION BY result_emp ORDER BY close_date) accu_sum
FROM ARSLT90T
WHERE close_date BETWEEN '20040101' AND '20041231'
AND result_emp = '2001053'
AND result_kind = '01'
) a,
( SELECT TO_CHAR(dum_days, 'yyyymmdd') dum_days
FROM (SELECT TO_DATE('20040101', 'yyyymmdd') -1 + ROWNUM AS dum_days
FROM all_objects
WHERE TO_DATE('20040101', 'yyyymmdd') -1 + ROWNUM < TO_DATE('20041231', 'yyyymmdd')
)
WHERE TO_CHAR(dum_days,'D') = '7'
) b
WHERE b.dum_days = a.close_date (+)
GROUP BY dum_days, a.close_date, a.result_emp, real_ord_amt
이와 같이 쿼리를 한 결과
| DUM_DAYS | RESULT_EMP | ACCU_SUM |
| 20040103 | 2001053 | 200 |
| 20040110 | ||
| 20040117 | ||
| 20040124 | ||
| 20040131 | ||
| 20040207 | ||
| 20040214 | ||
| 20040221 | ||
| 20040228 | ||
| 20040306 | ||
| 20040313 | ||
| 20040320 | ||
| 20040327 | ||
| 20040403 | 2001053 | 900 |
| 20040410 | ||
| 20040417 | ||
| 20040424 | ||
| 20040501 | ||
| 20040508 | ||
| 20040515 | ||
| 20040522 | ||
| 20040529 | 2001053 | 1300 |
| 20040605 | 2001053 | 2100 |
| 20040612 | ||
| 20040619 | 2001053 | 8000 |
| 20040626 | ||
| 20040703 | 2001053 | 10000 |
| 20040710 | ||
| 20040717 | ||
| 20040724 | ||
| 20040731 | 2001053 | 2500 |
| 20040807 | 2001053 | 4000 |
| 20040814 | ||
| 20040821 | ||
| 20040828 | 2001053 | 4200 |
| 20040904 | ||
| 20040911 | ||
| 20040918 | ||
| 20040925 | ||
| 20041002 | 2001053 | 4800 |
| 20041009 | 2001053 | 6200 |
| 20041016 | ||
| 20041023 | ||
| 20041030 | 2001053 | 8300 |
| 20041106 | ||
| 20041113 | 2001053 | 8600 |
| 20041120 | ||
| 20041127 | 2001053 | 9300 |
| 20041204 | 2001053 | 9700 |
| 20041211 | 2001053 | 10000 |
| 20041218 | ||
| 20041225 | 2001053 | 13000 |
위와 같이 이빨이 빠지는 부분이 있습니다.
20041218의 경우
20041218 2001053 2004810793
이런식으로 빈칸은 이전 row에서 값을 받아오도록
이빨이 빠진 곳들을 채워넣고 싶은데 쿼리가 쉽게 안떠오는군요.
쿼리는....
select dum_days,result_emp,max(accu_sum) over (partition by decode(xxx,null,0,xxx) ORDER BY dum_days) accu_sum_tot
from
(
SELECT dum_days, a.result_emp, accu_sum,sum(accu_sum) over (order by dum_days) xxx
FROM
( SELECT close_date, result_emp
, SUM(result_amt) over (PARTITION BY result_emp ORDER BY close_date) accu_sum
FROM ARSLT90T
WHERE close_date BETWEEN '20040101' AND '20041231'
AND result_emp = '2001053'
AND result_kind = '01'
) a,
( SELECT TO_CHAR(dum_days, 'yyyymmdd') dum_days
FROM (SELECT TO_DATE('20040101', 'yyyymmdd') -1 + ROWNUM AS dum_days
FROM all_objects
WHERE TO_DATE('20040101', 'yyyymmdd') -1 + ROWNUM < TO_DATE('20041231', 'yyyymmdd')
)
WHERE TO_CHAR(dum_days,'D') = '7'
) b
WHERE b.dum_days = a.close_date (+)
GROUP BY dum_days, a.close_date, a.result_emp, real_ord_amt
)
===============================================================
위에서 사용된 방법을 약간 응용해 보겠습니다.
다음과 같은 문제가 있습니다.
아래와 같은 데이타가 있을때 col_a라는 컬럼을 [결과]와 같이 만드는 쿼리가 있을까요?
|
rownum |
col_a |
|
1 |
a |
|
2 |
b |
|
3 |
12345 |
|
4 |
d |
|
5 |
67890 |
|
6 |
e |
|
7 |
f |
[결과]
|
rownum |
col_a |
|
1 |
12345 |
|
2 |
12345 |
|
3 |
12345 |
|
4 |
12345 |
|
5 |
67890 |
|
6 |
67890 |
|
7 |
67890 |
컬럼 값이 길이가 한자리라면 다음의 조건을 만족한 값을 가져야 합니다.
1. 이전 row의 숫자 값을 가져온다.
2. 이전 row의 컬럼 값의 길이가 한 자리라면 이전 row 중 가장 가까운 row의 숫자컬럼값을 가져온다.
2. 이전 row가 없을 경우에는 next row 들 중에서 가장 가까운 row의 숫자값을 가져온다.
3. 숫자값일 경우는 숫자값이 들어간다.
ps. rownum의 원래 순서는 유지해야 합니다.
쿼리는....
SELECT rownum#, DECODE (bb1, 0, bb2, bb1) cc1
FROM (SELECT rownum#,
MAX (col_a) OVER (PARTITION BY aa1 ORDER BY rownum#) bb1,
MAX (col_a) OVER (PARTITION BY aa2 ORDER BY rownum# DESC) bb2
FROM (SELECT ROWNUM rownum#,
DECODE (LENGTH (col_a), 1, 0, col_a) col_a,
SUM (DECODE (LENGTH (col_a), 1, 0, col_a)) OVER (ORDER BY ROWNUM)
aa1,
SUM (DECODE (LENGTH (col_a), 1, 0, col_a)) OVER (ORDER BY ROWNUM DESC)
aa2
FROM TEST))