database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40868 게시물 읽기
No. 40868
[급해요]중복 일수 제외하고 기간 구하기
작성자
초보자
작성일
2015-07-22 08:55ⓒ
2015-07-22 08:56ⓜ
조회수
9,525

안녕하세요.

 

도움이 절실하여 조언을 구하고자 글을 올립니다.

 

1번 SQL에서 수행한 정지기간 시작일자 / 종료일자 / 시작~종료일수 정보 입니다.

(해당 SQL 내에서 시작일자와 종료일자가 중복 발생 X : 20150601~02 / 20150602~12 이렇게 02일이 중복될 수 없음)

EX) 시작일자      종료일자    GAP(=종료일자-시작일자+1)

        20150601   20150602  2

        20150612   20150615  4

 

2번 SQL에서 수행한 무료기간 시작일자 / 종료일자  정보입니다.

(해당 SQL 내에서 시작일자와 종료일자가 중복 발생 X : 20150601~02 / 20150602~12 이렇게 02일이 중복될 수 없음)

 

EX) 시작일자      종료일자

        20150601    20150610

        20150612    20150614

        20150617    20150620

        20150621    20150625

 

이런 조건하에 정지기간과 무료기간 간에 겹치는 일자를 제외하여 

총 정지기간+무료기간 일수를 구해야 됩니다.

 

단건 수행하는 것이 아닌 각각의 고객에 대해 일자계산이 되어야 되는 부분이기에

함수를 사용할 경우 수행 속도에 영향이 있지 않을까 생각됩니다. (함수 구현도 막막하지만;;;)

 

제가 생각한 방식은

1. 배열을 이용해서 중복되는 일자를 제외하고 배열 카운트 = 오라클에 배열이 없는데...

2. 오라클 함수 생성하여 함수내에서 CONNECT BY LEVEL을 사용하여 일자를 나열한 후 UNION / DISTINCT 하여 카운트....

     = ROW가 유동적이라 다이나믹SQL로 구현할 실력이 안됨 / 다건 수행 시 수행 속도가 엄청 날 것으로 예상

 

1번도 2번도 제 실력으로는 아직 구현이 불가능합니다.

 

많은 고수님들 부디 조언과 답변을 아끼지 말아주세요. 도와주십시오. 감사합니다.

이 글에 대한 댓글이 총 4건 있습니다.

 간단 로직을 알려드리면

 

모든, 시작 종료 일자와 Type(시작, 종료)을 일자별로 정리하세요. 

그 다음, 시작일자는 +1, 종료일자는 -1 로 계산한 다음 sum을 partiton by, order와 함께 해준후에, 

sum 값이 0보다 큰 일자를 구하면, 정지 또는 무료 기간이 됩니다.

 

 

아싸가오리님이 2015-07-22 10:20에 작성한 댓글입니다. Edit

정기지간과 무료기간을 UNION ALL 한 후

CONNECT BY LEVEL을 사용 GROUP BY DT를 해서 COUNT(1) 하면

중복일수 제외하고 총 일수가 나오지만... 고객 1명에 대해서는 수행이 되는데

여러 고객에 대해 동시에 구할려니 CONNECT BY LEVEL을 사용할 수가 없어지는 것 같습니다.

함수로 만들어서 일수를 구해야 될까요?

초보자님이 2015-07-22 10:40에 작성한 댓글입니다. Edit

WITH 정지기간 AS
(
SELECT 1 id, '20150601' sdt, '20150602' edt FROM dual
UNION ALL SELECT 1, '20150612', '20150615' FROM dual
UNION ALL SELECT 2, '20150619', '20150622' FROM dual
)
, 무료기간 AS
(
SELECT 1 id, '20150601' sdt, '20150610' edt FROM dual
UNION ALL SELECT 1, '20150612', '20150614' FROM dual
UNION ALL SELECT 2, '20150617', '20150620' FROM dual
UNION ALL SELECT 2, '20150621', '20150625' FROM dual
)
SELECT id
     , SUM(edt - sdt + 1) days
  FROM (SELECT id
             , TO_DATE(MIN(sdt), 'yyyymmdd') sdt
             , TO_DATE(MAX(edt), 'yyyymmdd') edt
          FROM (SELECT id, sdt, edt
                     , SUM(flag) OVER(PARTITION BY id ORDER BY sdt, edt) grp
                  FROM (SELECT id, sdt, edt
                             , CASE WHEN MAX(edt) OVER(
                                         PARTITION BY id ORDER BY sdt, edt
                                         ROWS BETWEEN UNBOUNDED PRECEDING
                                                  AND 1 PRECEDING
                                         ) >= sdt
                                    THEN null ELSE 1 END AS flag
                          FROM (SELECT id, sdt, edt FROM 정지기간
                                 UNION ALL
                                SELECT id, sdt, edt FROM 무료기간
                                )
                        )
                )
         GROUP BY id, grp
        )
 GROUP BY id
 ORDER BY id
;

마농(manon94)님이 2015-07-22 11:03에 작성한 댓글입니다.
이 댓글은 2015-07-22 11:09에 마지막으로 수정되었습니다.

와...신기하게도 한 번에 되는군요 ㅠㅠ

CONNECT BY는 함수로 만들어서 고객별로  날짜비교하여 MINUS 하여 무료일수 때문에  추가된 겹치는 일자 리턴하게 해서 고객별로 무료일수 때문에 추가된 일자가 몇일이나 추가되었는지 정보 볼 수 있게 구현하였고, (이러면 기존에 정지일수 에 함수를 사용하여 나온 일수를 더하면 총 일수가 나오더라구요.)

여러 고객에 대해 한 번에 일수 구할 때는 마농님께서 주신 SQL을 바탕으로 배치프로그램으로 구현할 수 있을 것 같습니다. (ROWS BETWEEN UNNOINDED PRECENDING 공부 좀 할께요.)

큰 도움 주신 아싸가오리님과 마농님께 다시 한 번 고개 숙여 감사드립니다.

정말 큰 도움 되었습니다. 

초보자님이 2015-07-22 13:35에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
40871조직도를 만드는 쿼리가 계층쿼리 없이 되어 있어서 [4]
계층
2015-07-22
7820
40870혹시 이런게 가능한지요?? (고정컬렁횡 -> 로우로 변환) [2]
량디
2015-07-22
7956
40869그룹 번호 매기기 문의 드립니다. [2]
김미림
2015-07-22
7993
40868[급해요]중복 일수 제외하고 기간 구하기 [4]
초보자
2015-07-22
9525
40867마농님.... 도와 주세요... [4]
초초보
2015-07-20
7856
40866이거 모르겟네요;; [1]
이기쁨
2015-07-18
7602
40864간단한 쿼리 질문 ^^ 계층 구조 관련 [1]
kos
2015-07-17
7999
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.024초, 이곳 서비스는
	PostgreSQL v16.4로 자료를 관리합니다