데이터 추출 하는데 조금... 헷갈려요 ㅠㅠ 0 24 1,839

by 스파이 [SQL Query] [2016.05.04 11:15:47]


select c.centarea, min(b.managename) 구분,
       sum(d.cnt) 등록,
       sum(c.cnt) 활동,
	   sum(case when centtype >= '001' and centtype <= '010' then c.cnt else 0 end) 계,
       sum(decode(centtype,'003',c.cnt,0)) 아,
       sum(decode(centtype,'004',c.cnt,0)) 노,
       sum(decode(centtype,'005',c.cnt,0)) 장,
       sum(decode(centtype,'006',c.cnt,0)) 여,
       sum(decode(centtype,'008',c.cnt,0)) 정,
       sum(decode(centtype,'007',c.cnt,0)) 노,
       sum(decode(centtype,'009',c.cnt,0)) 복,
       sum(case when centtype in ('010','001','002') then c.cnt else 0 end) 법,
       sum(decode(centtype,'011',c.cnt,0)) 보,
       sum(case when centtype >= '012' then c.cnt else 0 end) 기타
  from centmst_blood_2015 a,
       managecode b,
      (select a.centarea, b.centcode,
	          count(distinct a.resno) cnt
	     from resactres_blood_2015 a, resmst_blood_2015 b
	     where a.resno = b.resno
        group by a.centarea, b.centcode) c,     -- 활동
      (select centcode,
	          count(*) cnt
	     from resmst_blood_2015
		where registedate  <= '2015-12-31'
        group by centcode) d      -- 등록
 where a.centarea  = b.managecode
   and b.largecode = 'CM00'
   and a.centcode  = c.centcode
   and a.centcode  = d.centcode
group by c.centarea;

 

C 의 엘리어스 데이터는 정상적으로 나옵니다만...

D 의 엘리어스도 이상할게 없지만


​ and a.centcode  = d.centcode 를 조인 해서 데이터를 출력하게 되면 이상하게 나옵니다.

         등록                          활동

중앙 6748435 186682
서울 6336845 291487
부산 4390587 78334

 

C와 D의 데이터는 값이 틀리기 떄문에 조인을 걸면 안되고...

정상적인 데이터로는

 

중앙                286,694                186,682
서울              1,412,319                291,487
부산                390,809                 78,334

 

이렇게 나와야 하는데 숫자만 바꾸면 되긴 하지만... 이게 장기적으로 사용될 예정이라..

애매합니다. ㅠㅠ 한 몇일 고민했는데 답이 안나와서 문의 드립니다.

조언 부탁드립니다.

 

by chrome [2016.05.04 13:26:54]

JOIN조건이

C는 유니크 한 조건이 아닌데 D는 유니크하니 D의 열 수가 C만큼 늘어나니까

결과가 다를 수 밖에요

 

 


by 스파이 [2016.05.04 13:40:18]

흐으음...

c,centarea 부분을 a.centarea 로 바꾼다면 가능하지 않을까 싶은데도...

정보가 이상하게 나오더라구요

 

밑에 where 절 부분을 보면

A테이블 컬럼 = C테이블 컬럼

A테이블 컬럼 = D테이블 컬럼

조인은 걸지만 

C테이블 컬럼 = D테이블 컬럼 조인을 걸지 않아

가능 하지 않을까요?

 

centmst 테이블 Base > min(b.managename) 구분,

                               sum(d.cnt) 등록,
                               sum(c.cnt) 활동
 
 

by 스파이 [2016.05.04 15:57:39]

원하는 데이터 추출 하려면 따로따로 출력 하는 방법 밖에 없을까요?...

하아...

답답하네요


by 마농 [2016.05.04 15:59:11]

테이블 명세나, 인덱스 정보, 자료 예시를 좀 보여 주세요.

테이블간의 관계를 알아야 답변 드릴 수 있을 듯 하네요.


by 스파이 [2016.05.04 16:46:37]
select a.centarea, min(b.managename) 구분,
       sum(d.cnt) 등록,
       sum(c.cnt) 활동,
       sum(case when centtype >= '001' and centtype <= '010' then c.cnt else 0 end) 계,
       sum(decode(centtype,'003',c.cnt,0)) 아,
       sum(decode(centtype,'004',c.cnt,0)) 노,
       sum(decode(centtype,'005',c.cnt,0)) 장,
       sum(decode(centtype,'006',c.cnt,0)) 여,
       sum(decode(centtype,'008',c.cnt,0)) 정,
       sum(decode(centtype,'007',c.cnt,0)) 노,
       sum(decode(centtype,'009',c.cnt,0)) 복,
       sum(case when centtype in ('010','001','002') then c.cnt else 0 end) 법,
       sum(decode(centtype,'011',c.cnt,0)) 보,
       sum(case when centtype >= '012' then c.cnt else 0 end) 기타
--(centtype 센터정보 컬럼 입니다, centmst_blood_2015 테이블에서 가져옵니다.)
  from centmst_blood_2015 a, --(센터정보 테이블)
       managecode b, --(공통코드 테이블)
      (select a.centarea, b.centcode,
              count(distinct a.resno) cnt
         from resactres_blood_2015 a, resmst_blood_2015 b
         where a.resno = b.resno
        group by a.centarea, b.centcode) c,     -- 활동 (활동한 사람과 고객정보가 일치하는지 확인)
      (select centcode,
              count(*) cnt
         from resmst_blood_2015
        where registedate  <= '2015-12-31'
        group by centcode) d      -- 등록 ( 2015-12-31일 이전까지 가입한 고객정보를 카운트)
 where a.centarea  = b.managecode --(지역코드)
   and b.largecode = 'CM00' --(지역구분코드)
   and a.centcode  = c.centcode --(활동 센터코드)
   and a.centcode  = d.centcode --(등록 센터코드)
group by a.centarea;

 

 


by 스파이 [2016.05.04 16:42:37]
구분 등록 활동 기타
중앙 6748435 186682 91754 10752 28583 23821 557 1499 1636 15003 9903 6435 88493
서울 6336845 291487 232468 21333 59746 54014 871 2010 2913 53967 37614 10224 48795

 

centmst_blood_2015 : 센터정보 테이블 ( pk: centcode         index : centcode, centarea)

managecode : 공통코드 테이블 ( pk: managecode    index : managecode)

resactres_blood_2015 : 활동이력 테이블 ( pk: RESNO           index : resno, centcode, centarea)

resmst_blood_2015 : 고객정보 테이블 ( pk: RESNO   index : resno, centcode)

RESNO(연번), centcode(센터번호), centarea(센터지역)

 

centmst_blood_2015의 센터 기준으로 resmst_blood_2015(고객정보) 2015-12-31일까지 가입한 클라이언트를 카운트 합니다.

centmst_blood_2015의 센터 기준으로 centtype(센터의 타입에 따라  resactres_blood_2015(활동내역) 을 카운트 합니다.

 

고객정보와 활동내역을 조인하지 않기 때문에 데이터가 따로따로 나와야 한다고 생각 하는데...

실상 생각했던 데이터와 값이 틀리게 나옵니다.


by 마농 [2016.05.04 17:03:01]

글쎄요? 뭐가 문제죠?
제시해 주신 정보를 보면 센터정보 A 를 기준으로
C 와 D 를 centcode 로 조인하네요.
C 와 D 어차피 centcode 로 그룹바이 된 상태이니
연결에는 아무 문제 없을 듯 한데요?


혹시
C 에서 resactres_blood_2015 와 resmst_blood_2015 를 res_no 로 조인하는데
  - 이 조인 맞는 건지?
Group BY 를 centarea 와 centcode 로 하는데?
  - centarea 는 결국 아무데도 안쓰이는데?
  - 굳이 왜 이렇게 하는지?


by 스파이 [2016.05.04 17:16:29]

C 에서 resactres_blood_2015 와 resmst_blood_2015 를 res_no 로 조인하는데
  - 이 조인 맞는 건지?

- 활동한 사람과 고객정보가 일치하는지 확인 하기 위해서 조인을 걸었습니다


Group BY 를 centarea 와 centcode 로 하는데?
  - centarea 는 결국 아무데도 안쓰이는데?
  - 굳이 왜 이렇게 하는지?

아... 그건 a.centarea  = b.managecode 이 부분을 

c.centarea로 한번 테스트 하기 위해서 넣었습니다.

위에 쓰인 쿼리에서는 필요가 없네요 ㅠㅠ

 


by 마농 [2016.05.04 17:24:15]

올려주신대로라면 문제될게 하나도 없습니다.
c 와 d 는 centcode 로 Group By 했고
나머지 a 는 centcode가 유일키이고
b 도 managecode 가 유일키 이므로
전혀 문제될것이 없습니다.
올려주신 PK 가 맞는지 의심스럽네요?


by 스파이 [2016.05.04 17:36:32]

테이블별 스샷을 다찍었는데...

ck에디터 이미지 업로드가 URL 형식이네요

현재 올려드린 pk는 전체는 아니지만...

현재 사용된 컬럼에 대해서는 맞습니다

 


by 마농 [2016.05.04 17:40:48]

PK 일부만 올리셨다면?

 - 문제 해결에 전혀 도움이 안됩니다.

 - 중복 자료로 인한 카티션 곱 발생 가능성이 있습니다.


by 스파이 [2016.05.04 17:49:13]

헉!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

centmst_blood_2015 : 센터정보 테이블 ( pk: centcode, largecode  index : centcode, centarea)

managecode : 공통코드 테이블 ( pk: managecode    index : managecode)

resactres_blood_2015 : 활동이력 테이블 ( pk: RESNO, actdate, actseq        index : resno, centcode, centarea)

resmst_blood_2015 : 고객정보 테이블 ( pk: RESNO   index : resno, centcode)

 

centmst_blood_2015 테이블과 resactres_blood_2015 테이블에 pk 추가 했습니다.

나머지 테이블은 변동 없습니다.


by 마농 [2016.05.04 17:54:39]

largecode 는 센터정보가 아닌 공통코드의 PK 인 듯 하구요?
 - 잘못 적으신거죠?
위 정보대로라면 전혀 문제될 게 없어 보입니다.
 - 실제 데이터 예로 문제점을 설명해 주세요.
 - 뭐가 문제인지?


by 스파이 [2016.05.04 17:59:25]

아아아!! 잘못 적었네요 네네 맞습니다. 공통테이블의 정보 입니다.

 

데이터가 

         등록                          활동

중앙 6748435 186682
서울 6336845 291487
부산 4390587 78334

이렇게 나옵니다.

 

제가 생각하는 나와야할 데이터는

중앙 286,694 186,682
서울 1,412,319 291,487
부산 390,809 78,334

입니다.

 

등록쪽의 데이터가 너무 많이 나와서...

쿼리상 무슨 문제가 있지 않나 싶어서 문의 드렸습니다.


by 마농 [2016.05.04 18:48:47]
숫자만 달랑 적어서 어떻게 아나요?
나와야 할 데이터에 대한 근거 자료를 예시 주셔야죠.

by 스파이 [2016.05.04 19:14:19]

근거라고 하자면... 등록 부분의 서브쿼리 데이터만 따로 돌려보면 나오는 데이터와 상이 합니다.


by 마농 [2016.05.04 21:12:35]
등록 부분에서는 센터로 집계했는데?
지역 집계는 어찌 확인한거죠?

by 스파이 [2016.05.05 09:24:58]

지역 집계 부분은 지역이 많지 않기 때문에 센터코드별 어디 지역인지 확인이 가능 합니다.

 


by 스파이 [2016.05.05 17:44:32]
select a.centarea, min(b.managename) 구분,
       sum(d.cnt) 등록
  from centmst_blood_2015 a,
       managecode b,
      (select centcode,
	          count(*) cnt
	     from resmst_blood_2015
		where registedate  <= '2015-12-31'
        group by centcode) d      -- 등록
 where a.centarea  = b.managecode
   and b.largecode = 'CM00'
   and a.centcode  = d.centcode
group by a.centarea;

 

이렇게 추출 하면 데이터 확인 가능합니다

하아....그냥 따로 추출 해야 겠습니다 ㅠㅠ

이유가 뭔지 모르겠네요

조언 감사합니다~


by 마농 [2016.05.09 10:21:35]

서브쿼리 C 안의 그룹바이 구문에서
group by a.centarea, b.centcode 이렇게 하신거 아니죠?
group by b.centcode 이렇게 하셔야 하는데요.
물론 centcode 에 해당하는 centarea 는 하나 뿐일 듯 하지만...
혹시 centcode 에 해당하는 centarea 가 두개 이상 나올 수도 있다면?
카티션곱이 발생하여 데이터가 중복 집계 될 수 있습니다.


by 스파이 [2016.05.09 11:43:07]

서브쿼리 C 안의 centarea 부분 지워 보고 테스트 해보겠습니다.

 


by 스파이 [2016.05.10 11:06:49]
select c.centarea, min(b.managename) 구분,
  		 sum(d.cnt) 등록,
       sum(c.cnt) 활동,
	   sum(case when centtype >= '001' and centtype <= '010' then c.cnt else 0 end) 계,
       sum(decode(centtype,'003',c.cnt,0)) 아,
       sum(decode(centtype,'004',c.cnt,0)) 노,
       sum(decode(centtype,'005',c.cnt,0)) 장,
       sum(decode(centtype,'006',c.cnt,0)) 여,
       sum(decode(centtype,'008',c.cnt,0)) 정,
       sum(decode(centtype,'007',c.cnt,0)) 노,
       sum(decode(centtype,'009',c.cnt,0)) 복,
       sum(case when centtype in ('010','001','002') then c.cnt else 0 end) 법,
       sum(decode(centtype,'011',c.cnt,0)) 보,
       sum(case when centtype >= '012' then c.cnt else 0 end) 기타
  from centmst_blood_2015 a,
       managecode b,
      (select a.centarea, b.centcode,
	          count(distinct a.resno) cnt
	     from resactres_blood_2015 a, resmst_blood_2015 b
	     where a.resno = b.resno
        group by a.centarea, b.centcode) c,     -- 활동
(select centcode,
	          count(*) cnt
	     from resmst_blood_2015
		where registedate  <= '2015-12-31'
        group by centcode) d      -- 등록
 where c.centarea  = b.managecode
   and b.largecode = 'CM00'
   and a.centcode  = c.centcode
   and a.centcode  = d.centcode
group by c.centarea;

 

확실히 이렇게 데이터 추출하니깐 말씀하신 카디션곱이 발생한 것 같습니다.

그래서 결론은... 한번에 출력하면 안되겠네요... ㅎㅎ;

감사합니다!!!

 


by 마농 [2016.05.10 11:19:20]

결론이 왜 엉뚱하게 날까요?

카티션 곱이 발생하는 원인을 제거해야죠?


by 스파이 [2016.05.10 14:22:25]

지금 사용하고 있는 테이블 들이 전부 임시 테이블스페이스를 생성해서 만든 후

사전작업을 하는 부분이 있는데 resactres_blood_2015, centmst_blood_2015의 centcode가 맞지 않아서 일어나는 것 같아 

사전작업 작업 중  resactres_blood_2015 부분 centmst_blood_2015 테이블과 비교 update 하는 부분이 이상하게 되어 있어 수정 후 다시 쿼리 돌려보니 정상적으로 나옵니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입