SQL질문 드립니다. 0 6 1,367

by 박동혁 [2007.11.27 17:59:21]


안녕하세요.

SQL추출이 잘 되지 않아서 도움 청합니다.

 

현재 총6개의 테이블을 조인해서 데이터를 뽑아낼려고 합니다.

개략적인 내용을 보면...

----------------------------------------------------------
1. 계약마스터 : 추출 조건에 들어맞는 것 모두 취득
2. 속성마스터 : "고객번호"가 "계약마스터.고객번호"와 일치하는 것 취득
3. 속성상세 : "고객번호"가 "계약마스터.고객번호"와 일치하는 것 취득
4. 입금 : "고객번호", "계약번호"가 "계약마스터.고객번호", "계약 마스터.계약번호"와 일치하는 것 취득
    레코드가 다수 있는 경우는, "입금연월일", "통번"이 최대로, "취소구분"이 NULL인 데이터를 대상으로 한다.
5. 상품명세 : "제휴처코드", "고객번호", "계약번호"가 "계약마스터(제휴처코드, 고객번호, 계약번호)"와 일치한 것 취득
    레코드가 다수 있는 경우는, "상품종별코드", "발생일", "상품 번호"가 최대의 데이터를 대상으로 한다.
6. 이율 : "상품종별코드", "상품번호"가 "상품명세.상품종별코드", "상품명세.상품번호"와 일치하는 것 취득
    레코드가 다수 있는 경우는, 최종이동분의 "입금.입금연월일" 이전으로, "이율적용개시일"이 최대의 데이터를 대상으로 한다.   

 

위에서 1번, 2번, 3번의 경우는 단순해서 문제가 되지 않는데요.

4번, 5번, 6번이 문제입니다.

MAX값이 하나면 괜찮은데....MAX값은 2개 혹은 3개를 조건으로 해야해서...그게 잘 안됩니다.

 

현재 만들어 놓은 SQL이 아래와 같습니다.

------------------------------------------------------------------------

SELECT
  계약마스터.계약번호 
 ,계약마스터.해제구분 
 ,속성상세.배분코드 
 ,계약마스터.채권분류코드 
 ,SUBSTR(계약 마스터.제휴처 코드,-2,2) 
 ,계약마스터.상품종별코드 
 ,속성마스터.이름
 ,속성마스터.성별
 ,To_char(To_DATE(속성마스터.생년월일)) 
 ,FLOOR(MONTHS_BETWEEN(To_date(계약마스터.계약연월일),TO_DATE(속성마스터.생년월일))/12) AS 연령 
 ,To_char(계약마스터.당초대출금, '999,999,999,990') 
 ,To_char(계약마스터.대변실행액, '999,999,999,990') 
 ,계약마스터.과목번호 
 ,계약마스터.계좌번호 
 ,속성마스터.CIF번호 
 ,To_char(To_DATE(입금.입금처리연월일)) AS 기입일
 ,To_char(To_DATE(입금.입금연월일)) AS 기산일
 ,To_char(상품명세.원본잔고, '999,999,999,990') AS 구상권잔고
 ,To_char(상품명세.지연손해금잔고, '999,999,999,990') AS 지손실금잔고
 ,To_char(이율.지연손해금율, '99.0000') AS 지손실금이율
FROM 계약마스터,
 속성마스터,
 속성상세,
 (SELECT 입금.계약번호 AS 계약번호
   ,입금.고객번호 AS 고객번호
   ,입금.입금연월일 AS 입금연월일
   ,MAX(입금.통번) AS 통번
   ,SUBSTR(MAX(LPAD(입금.통번, 4,'0')||입금.입금처리연월일),5) AS 입금처리연월일
  FROM 입금, 계약마스터
  WHERE 계약마스터.계약번호 = 입금.계약번호
  AND 계약마스터.고객번호 = 입금.고객번호
  AND (입금.취소구분 is NULL OR 입금.취소구분 = '')
  GROUP BY 입금.계약번호, 입금.고객번호, 입금.입금연월일) 입금,
 (SELECT 상품명세.제휴처코드 AS 제휴처코드
   ,상품명세.고객번호 AS 고객번호
   ,상품명세.계약번호 AS 계약번호
   ,MAX(상품명세.상품종별코드) AS 상품종별코드
   ,SUBSTR(MAX(LPAD(상품명세.상품종별코드, 4,'0')||상품명세.원본잔고),5) AS 원본잔고
   ,SUBSTR(MAX(LPAD(상품명세.상품종별코드, 4,'0')||상품명세.지연손해금잔고),5) AS 지연손해금잔고
   ,SUBSTR(MAX(LPAD(상품명세.상품종별코드, 4,'0')||상품명세.상품번호),5) AS 상품번호
  FROM 계약마스터, 상품명세
  WHERE 계약마스터.제휴처코드 = 상품명세.제휴처코드
  AND 계약마스터.고객번호 = 상품명세.고객번호
  AND 계약마스터.계약번호 = 상품명세.계약번호
  GROUP BY 상품명세.제휴처코드, 상품명세.고객번호, 상품명세.계약번호) 상품명세,
 (SELECT 이율.상품종별코드 AS 상품종별코드
   ,상품명세.상품번호 AS 상품번호
   ,MAX(이율.이율적용개시일) AS 이율적용개시일
   ,SUBSTR(MAX(LPAD(이율.이율적용개시일, 4,'0')||이율.지연손해금율),5) AS 지연손해금율
  FROM 이율, 상품명세
  WHERE 상품명세.상품종별코드 = 이율.상품종별코드
  AND 상품명세.상품번호 = 이율.상품번호
  GROUP BY 이율.상품종별코드, 상품명세.상품번호) 이율
WHERE 계약마스터.제휴처코드 = '000101'
AND 계약마스터.고객번호 = 속성마스터.고객번호
AND 계약마스터.고객번호 = 속성상세.고객번호
AND (계약마스터.고객번호 = 입금.고객번호
AND 계약마스터.계약번호 = 입금.계약번호)
AND (계약마스터.제휴처코드 = 상품명세.제휴처코드
AND 계약마스터.고객번호 = 상품명세.고객번호
AND 계약마스터.계약번호 = 상품명세.계약번호
AND 계약마스터.상품종별코드 = 상품명세.상품종별 코드)
AND (상품명세.상품종별코드 = 이율.상품종별코드
AND 상품명세.상품번호 = 이율.상품번호)

------------------------------------------------------------------------

 

아무래도 문제가 되는 부분은

 

4번부분인......↓요부분

(SELECT 입금.계약번호 AS 계약번호
   ,입금.고객번호 AS 고객번호
   ,입금.입금연월일 AS 입금연월일
   ,MAX(입금.통번) AS 통번
   ,SUBSTR(MAX(LPAD(입금.통번, 4,'0')||입금.입금처리연월일),5) AS 입금처리연월일
  FROM 입금, 계약마스터
  WHERE 계약마스터.계약번호 = 입금.계약번호
  AND 계약마스터.고객번호 = 입금.고객번호
  AND (입금.취소구분 is NULL OR 입금.취소구분 = '')
  GROUP BY 입금.계약번호, 입금.고객번호, 입금.입금연월일) 입금


 

5번 부분인 ↓요부분

 (SELECT 상품명세.제휴처코드 AS 제휴처코드
   ,상품명세.고객번호 AS 고객번호
   ,상품명세.계약번호 AS 계약번호
   ,MAX(상품명세.상품종별코드) AS 상품종별코드
   ,SUBSTR(MAX(LPAD(상품명세.상품종별코드, 4,'0')||상품명세.원본잔고),5) AS 원본잔고
   ,SUBSTR(MAX(LPAD(상품명세.상품종별코드, 4,'0')||상품명세.지연손해금잔고),5) AS 지연손해금잔고
   ,SUBSTR(MAX(LPAD(상품명세.상품종별코드, 4,'0')||상품명세.상품번호),5) AS 상품번호
  FROM 계약마스터, 상품명세
  WHERE 계약마스터.제휴처코드 = 상품명세.제휴처코드
  AND 계약마스터.고객번호 = 상품명세.고객번호
  AND 계약마스터.계약번호 = 상품명세.계약번호
  GROUP BY 상품명세.제휴처코드, 상품명세.고객번호, 상품명세.계약번호) 상품명세

 

6번 부분인 ↓요부분 

(SELECT 이율.상품종별코드 AS 상품종별코드
   ,상품명세.상품번호 AS 상품번호
   ,MAX(이율.이율적용개시일) AS 이율적용개시일
   ,SUBSTR(MAX(LPAD(이율.이율적용개시일, 4,'0')||이율.지연손해금율),5) AS 지연손해금율
  FROM 이율, 상품명세
  WHERE 상품명세.상품종별코드 = 이율.상품종별코드
  AND 상품명세.상품번호 = 이율.상품번호
  GROUP BY 이율.상품종별코드, 상품명세.상품번호) 이율

 


 

이렇게 세곳에서 조건을 충족시키지 못하고 있는것 같습니다.

이중에서 한곳만 해결이 되어도 다른곳은 그걸 바탕으로 할수 있지 않을까 싶습니다.

 

 

 

4번의 입급테이블을 더 자세히 설명드리면.....

계약번호, 고객번호, 입금연월일, 입금연월일, 통번이 모두 키값입니다.

 

데이터예제)

---------------------------------------------------------------------------

계약번호     고객번호     입금연월일    통번 

---------------------------------------------------------------------------

00000001     AAAAAA      20070102      0

00000001     AAAAAA      20070102      1

00000001     AAAAAA      20071111      0

00000001     AAAAAA      20071112      0

00000201     BBBBBB      20070102      0

00000201     BBBBBB      20070102      1

00000201     BBBBBB      20071020      0

99999999     TTTTTT      20070102      0

99999999     TTTTTT      20070102      1

99999999     TTTTTT      20070113      0

99999999     TTTTTT      20070113      1

---------------------------------------------------------------------------

 

위와 같이 데이터가 있다면 아래와 같은 결과를 얻고 싶습니다.

---------------------------------------------------------------------------

계약번호     고객번호     입금연월일    통번 

---------------------------------------------------------------------------

00000001     AAAAAA      20071112      0

00000201     BBBBBB      20071020      0

99999999     TTTTTT      20070113      1

---------------------------------------------------------------------------

 

많이는 적었는데....설명이 제대로 된지 모르겠습니다.

그럼, 고수님들의 조언 기다리겠습니다.

 

그리고, 지금 속도가 엄청 느립니다.

위에 SQL돌리면 3-5분이 걸리는데...이거 어떻게 빨리 되게 할수 있나요?

 

그럼, 즐거운 저녁시간 되시길 바라며 부탁드리겠습니다. 감사합니다..^^*

 

 

by finecomp [2007.11.27 00:00:00]
일단 인라인뷰안에서 입금만 상품명세만 이율만 group by 하시고 수행 해 보세요...;
상수조건도 없이 너무나 많은 수의 불필요한 조인이 일어나고 있습니다.

건승하시길...수고하세요~~

by 마농 [2007.11.28 00:00:00]
일단 입금만 본다면 조인키는 계약번호와 고객번호 두개입니다.
그렇다면 이 두개의 키값당 1행이 나와야 하는데
그러려면 group by 에서 이 두개 항목만 나와야겠죠.
지금은 입금연월일까지 나오고 있습니다. 일단 이걸 빼야죠.
또헌 입금과 계약 마스터를 두번 조인하는데 한번만 하면 되지요. 인라인뷰 안에서의 계약마스터를 빼세요.
SELECT 계약번호
, 고객번호
, MAX(입금연월일) 입금연월일
, SUBSTR(MAX(입금연월일||통번),9) 통번
FROM 입금
WHERE 입금.취소구분 IS NULL
GROUP BY 계약번호, 고객번호
적다보니 OR 입금.취소구분 = '' 이런 쓸데없는 조건도 있군요. 요것도 빼세요.

by 박동혁 [2007.11.28 00:00:00]
finecomp님, 마농님~
답변 감사드립니다.
덕분에 속도도 빨라지도 많이 좋아졌습니다.
아직 이율 뽑아오는게 잘 안되어서 지금은 그거 하고 있습니다.
더불어, 마농님 결혼두 축하 드려요~

by 마농 [2007.11.28 00:00:00]
감사합니다. *^-^*

by finecomp [2007.11.28 00:00:00]
(SELECT 이율.상품종별코드 AS 상품종별코드
,이율.상품번호 AS 상품번호
,MAX(이율.이율적용개시일) AS 이율적용개시일
,SUBSTR(MAX(LPAD(이율.이율적용개시일, 4,'0')||이율.지연손해금율),5) AS 지연손해금율
FROM 이율
GROUP BY 이율.상품종별코드, 이율.상품번호) 이율

참고하세요...^^;

by 박동혁 [2007.11.28 00:00:00]
finecomp님~
감사합니다.
그런데 조건에서...
--------------------------------
레코드가 다수 있는 경우는, 최종이동분의 "입금.입금연월일" 이전으로, "이율적용개시일"이 최대의 데이터를 대상으로 한다.
---------------------------------
'이율적용개시일'이 '입금.입금연월일'이전이면서 최대인 데이터를 찾는 것이라서요...
현재, 이래저래 해보다가 잘 안되어서...
'이율.지연손해금율'은 따로 SQL을 하나 더 만들었습니다.
한개로 되면 좋은데...잘 안 되어서요...^^*

덕분에 오늘두 많이많이 배우고 있습니다.
감사드립니다~
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입