CAFE

참고하세요. 쿼리!

빈날짜 집어넣고 데이터 채워 넣기

작성자원쿼리맨|작성시간05.11.29|조회수3,500 목록 댓글 0

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))

 

 

 

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼