누적합에서 구하는 쿼리에서 질문입니다. 0 6 5,986

by 김동영 누적합 distinct [2009.12.16 10:21:22]


해당월
A 상품
B 상품
전체
누적명수

 유효명수

누적명수

유효명수

유효명수
2009-12
5000
4682
50
47
4712
2009-11
4000
3721
40
37
3729
2009-10
3000
2736
30
28
2739
2009-09
2000
1823
20
18
1825
2009-08
1000
982
10
9
981

구하고자 하는 데이터 포맷은 위와 같습니다.

 

매월 A 상품과 B 상품을 가입하는 사람들 의 통계를 구하려고 합니다.

누적명수는 순수하게 매월 유입되는 명수를 더한 수입니다.

유효명수는 현재시간 기준으로 탈퇴한 회원수를 빼고 난 유효명수를 계산한겁니다.

 

여기서 문제는 해당 A 상품을 2009년 8월에도 가입할수 있고 2009년 9월에도 가입할수 있다는 겁니다.

그렇기 때문에 해당월에 보면 누적명수는 2009년 9월에 유효명수에서는 8월에 가입한 사람을 빼야 하므로

매월 유효명수는 이전데이터에 대해서 DISTINCT 가 되어야 합니다.

전체 누계에서는 이문제가 A 상품과 B 상품을 둘다 가입한 사람은 한사람으로 DISTINCT 해야 하는데요...

테이블은 mstr_info 하나이며 구성은 아래와 같습니다.

한사람이 같은 상품을 구입한 경우에는 seq_no 만 증가시켜 row 를 추가합니다.

해지해도 데이터는 삭제하지 않으며 상태코드만 변경한후 row 를 보관합니다.

SEQ_NO NUMBER(7) 000001 일련번호
RSDT_NO CHAR(13) XXXXXXXXXXXXX 주민번호
GODS_KIND_TYPE_CD CHAR(1) A 상품코드 (A/B 상품만 존재)
GODS_STTS_CD CHAR(1) 1 상품 상태코드(1:정상, 9:해지)
ISSU_DT CHAR(8) 20091215 구입일자
CLSE_LOST_DT CHAR(8) 20091215 해지일자
GODS_CLSE_RSN_CD VARCHAR2(2) 20 해지사유코드
FST_RGST_DT CHAR(8) 20091215 최초등록일자
LST_CHNG_DTTM CHAR(14) 20091215101213 최종수정일시
LST_CHNG_ID VARCHAR(20) tarzan12 최종수정 ID

 

어떻게 풀어야 할지 감이 안잡힙니다....

 

도움을 청하고 싶습니다..  

 

P.S 1 댓글에 첨부합니다.

 

저위에 데이터 포맷으로 예를 들면
2009년 8월 부터 A상품은 한달에 1000명씩 가입했습니다.
그래서 누적명수는 한달에 1000명씩 더해서 12월달에 5000명이 된것이고요.

유효명수는 현재날짜 12월15일날 조회했을때 상품상태가 정상인것들만 조회해서 각달까지 가입한 유니크한주민번호를 가진 사람의 수를 구한것입니다.


제가 설명을 제대로 못한것 같아 죄송합니다.

 

지금 현재 누적명수는

 SELECT A.ISSU_DT,
       SUMCD ,
       SUM(SUMCD) OVER (ORDER BY A.ISSU_DT ROWS UNBOUNDED PRECEDING) ROLLSUMCD,
       SUMCK,
       SUM(SUMCK) OVER (ORDER BY A.ISSU_DT ROWS UNBOUNDED PRECEDING) ROLLSUMCK
     FROM
     (SELECT ISSU_DT,
         SUM(SUMCD) SUMCD,
         SUM(SUMCK) SUMCK
       FROM (SELECT SUBSTR(ISSU_DT,1,6) ISSU_DT,
           DECODE(GODS_KIND_TYPE_CD,'A',COUNT(RSDT_NO),0) SUMCD,
           DECODE(GODS_KIND_TYPE_CD,'B',COUNT(RSDT_NO),0) SUMCK
        FROM GODS_MSTR_INFO
       GROUP BY ISSU_DT, GODS_KIND_TYPE_CD
         )
         GROUP BY ISSU_DT) A
         ORDER BY A.ISSU_DT

이런식으로 구한 상태인데요..

최종 유효명수는

select count(distinct(rsdt_no)) from  GODS_MSTR_INFO WHERE GODS_STTS_CD ='1'

을 했을때의 결과값이 동일하게 나와야 하는데.. 이부분을 해결 못하고 있습니다.

 

by 마농 [2009.12.16 10:45:42]
누적이라는 개념과 전월 가입자는 제외시킨다는 말과는 완전 상반되는 개념인데요?
탈퇴했다 다시 가입하는 경우엔 1번 카운트하나요? 두번 카운트 하나요?
좀 더 명확하게 설명해주시면 좋겠구요.
아예 샘플자료와 그에 따른 결과자료를 보여주시면 더욱 좋습니다.

by 김동영 [2009.12.16 10:51:15]
제가 질문을 좀 애매하게 올렸나 봅니다..
여기서 누적명수는 전월가입자도 카운트 하는거고요.
유효명수는 전월가입자를 제외한 명수를 말합니다.
탈퇴했다가 다시 가입하는 경우는 1번만 카운트 하게됩니다.

샘플자료는 row 데이터 밖에 없어서 별 도움이 되지 못할것 같습니다.. ㅜㅜ
매일 a 상품 , b 상품 에 대한 가입/ 탈퇴 로우데이터만 존재합니다. 현재..

by 마농 [2009.12.16 11:20:41]
별 도움이 안되는 것이 아니죠.
오히려 원시데이터를 알지 못하고서 어떻게 결과를 도출하나요?

가입, 탈퇴를 어떤식으로 관리하는지?
가입일자, 탈퇴일자가 따로 존재하는지?
아니면 다른 형태로 관리되는지? 테이블이 하나인지 둘인지?
한사람이 같은 상품을 두번 가입하는 경우는 없는지?
고려해야할 사항이 너무나도 많습니다.

by 마농 [2009.12.16 12:44:52]
설명을 곰곰히 들어보면
누적명수는 중복 인원과 상관 없이 무조건 월별 가입건수만 누적으로 구하면 되는 것이고
유효명수는 월별로 신규가입한 사람중 가입달에 바로 해지하지 않은 건수인듯 합니다만...
제 해석이 맞나요?
아직도 애매한 부분이 많습니다.
별도의 해석이 필요 없이 직관적으로 알아볼 수 있게 설명해 주세요.

by 마농 [2009.12.16 17:16:20]
특정일 기준 유효한 것을 뽑으면서 중복인원을 배제하려면
테이블을 한번 읽어서는 힘들 것 같습니다.

SELECT issu_dt
, MIN(DECODE(gods_kind_type_cd,'A',cnt1)) sumcd
, MIN(DECODE(gods_kind_type_cd,'A',cnt2)) rollsumcd
, MIN(DECODE(gods_kind_type_cd,'B',cnt1)) sumck
, MIN(DECODE(gods_kind_type_cd,'B',cnt2)) rollsumck
FROM (SELECT SUBSTR(issu_dt,1,6) issu_dt
, gods_kind_type_cd
, SUM(COUNT(*)) OVER(APRTITION BY gods_kind_type_cd ORDER BY SUBSTR(issu_dt,1,6)) cnt1
, (SELECT COUNT(DISTINCT rsdt_no)
FROM gods_mstr_info
WHERE gods_kind_type_cd = a.gods_kind_type_cd
AND issu_dt <= SUBSTR(a.issu_dt,1,6)||'31'
AND NVL(clse_lost_dt,'99991231') > SUBSTR(a.issu_dt,1,6)||'31'
) cnt2
FROM gods_mstr_info a
GROUP BY SUBSTR(issu_dt,1,6), gods_kind_type_cd
)
GROUP BY issu_dt
ORDER BY issu_dt
;

by 김동영 [2009.12.18 10:28:46]
마농님 친절하신 답변 감사합니다.. 다음 질문올릴때 질문 형식도 참고하겠습니다.. ^^
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입