2009-08-04 4 views
1

질문 : this question in regard to SQL Server,하지만 오라클 환경 (10g)에 대한 대답은 무엇입니까?Oracle SQL을 사용하여 스케줄 정보에서 실제 날짜를 그릴 수 있습니까?

특정 날짜를 의미하는 일정 정보가 포함 된 테이블이있는 경우 MSSQL의 Commom Table Expressions 같은 것을 사용하여 해당 정보를 실제 행으로 변환 할 수있는 SQL 문이 있습니까? 의 달에 길이 - 일정이 시작되는 날짜 (1 지불이 날짜에 의한)

  • 기간 -

    • STARTDATE가 :

      다음 열이있는 지불 일정 테이블을 고려 일정
    • 주파수 - 재발 사이의 개월 수
    • PaymentAmt -
     
    SchedID StartDate Term Frequency PaymentAmt 
    ------------------------------------------------- 
    1  05-Jan-2003 48 12   1000.00 
    2  20-Dec-2008 42 6   25.00 
    

    나 다음에 위에서 갈 수 있도록 하나의 SQL 문이 있습니까

  • :-) 결제 금액?

     
               Running 
    SchedID Payment Due   Expected 
         Num  Date   Total 
    -------------------------------------- 
    1  1  05-Jan-2003 1000.00 
    1  2  05-Jan-2004 2000.00 
    1  3  05-Jan-2005 3000.00 
    1  4  05-Jan-2006 4000.00 
    2  1  20-Dec-2008 25.00 
    2  2  20-Jun-2009 50.00 
    2  3  20-Dec-2009 75.00 
    2  4  20-Jun-2010 100.00 
    2  5  20-Dec-2010 125.00 
    2  6  20-Jun-2011 150.00 
    2  7  20-Dec-2011 175.00 
    

    귀하의 의견에 감사드립니다.

    답변

    1

    나는 내 자신의 질문에 대답하기 위해 나섰지 만, 나는 오라클과 지금 일하고 있으며 오라클의 새로운 맛을 배워야했습니다.

    어쨌든, 문 BY 연결 정말 좋은 - 예, MSSQL의 hierchical 쿼리 접근 방식, 그리고보다 훨씬 좋네요 그 구조를 사용하여, 내가 찾던 않는 매우 깨끗한 쿼리를 생성 할 수 있었다 :

    SELECT DISTINCT 
        t.SchedID 
        ,level as PaymentNum 
        ,add_months(T.StartDate,level - 1) as DueDate 
        ,(level * t.PaymentAmt) as RunningTotal 
    FROM SchedTest t 
    CONNECT BY level <= (t.Term/t.Frequency) 
    ORDER BY t.SchedID, level 
    

    나의 유일한 나머지 이슈는 내가 가지고있는 일정 데이터 테이블 대신에 DUAL (친숙한 1 행의 오라클 테이블)에서 내 행을 선택하는 방법을 알 수 없기 때문에 DISTINCT를 사용해야한다는 것입니다. 최소 2 개의 행. FROM DUAL로 위와 같은 작업을 수행 할 수 있다면 DISTINCT 표시기가 필요하지 않습니다. 이견있는 사람?

    그 외, 나는 이것이 꽤 좋다고 생각합니다. Et tu?

    1

    Oracle에는 실제로 CONNECT BY 절을 사용하는 계층 적 쿼리 구문이 있습니다. 내가 그에 100 % 해요

    SELECT t.SchedId, 
          CASE LEVEL 
          WHEN 1 THEN 
           t.StartDate 
          ELSE 
           ADD_MONTHS(t.StartDate, t.frequency) 
          END 'DueDate', 
          CASE LEVEL 
          WHEN 1 THEN 
           t.PaymentAmt 
          ELSE 
           SUM(t.paymentAmt) 
          END 'RunningExpectedTotal' 
         FROM PaymentScheduleTable t 
        WHERE t.PaymentNum <= t.Term/t.Frequency 
    CONNECT BY PRIOR t.startdate = t.startdate 
        GROUP BY t.schedid, t.startdate, t.frequency, t.paymentamt 
        ORDER BY t.SchedId, t.PaymentNum 
    

    - 사용에 대한 좀 더 확신 : 다음 WITH 절의 SQL 서버의 사용에 비해 해킹과 같은

    SELECT t.SchedId, 
          t.StartDate 'DueDate', 
          t.PaymentAmt 'RunningExpectedTotal' 
         FROM PaymentScheduleTable t 
        WHERE t.PaymentNum <= t.Term/t.Frequency 
    CONNECT BY PRIOR t.startdate = t.startdate 
        ORDER BY t.SchedId, t.PaymentNum 
    

    ...하지만 두 번째 + 항목을 체인에서 처리 할 때 처리 할 논리를 포함하지 않으므로 개월을 추가하여 & 금액을 합산합니다. 합계는 필요한 세부 사항에 따라 GROUP BY CUBE 또는 ROLLUP으로 수행 할 수 있습니다.

    +0

    나는 당신이 제안한 것을 시도하고 있지만 나는별로 행운이 없다. 두 번째 쿼리는 무한 루프를 발생시킵니다. 어떻게 피할 수 있습니까? – witttness

    +0

    이전 열 때 동일한 열을 가리키는 연결로 연결했는지는 확실하지 않았습니다. 테스트 할 Oracle이 없습니다. 나도 실종됐다 "q.PaymentNum <= s.Term/s.Frequency" –

    +0

    실제로 시작 순서를 나타내는 순서대로 연결하도록 업데이트되었지만 동일한 것을 가리킬 수 있는지 여부는 모르겠습니다. 기둥. –

    1

    schedid = 1 일 경우 5 일, scheid = 2 일 경우 7 일을 왜 이해하지 못합니까? 지금

    create table PaymentScheduleTable 
    (schedid number(10) 
    , startdate date 
    , term  number(3) 
    , frequency number(3) 
    , paymentamt number(5) 
    ); 
    
    insert into PaymentScheduleTable 
    values (1,to_date('05-01-2003','dd-mm-yyyy') 
    , 48 
    , 12 
    , 1000); 
    
    insert into PaymentScheduleTable 
    values (2,to_date('20-12-2008','dd-mm-yyyy') 
    , 42 
    , 6 
    , 25); 
    
    commit; 
    

    과 함께 선택 :

    12분의 48 = 4 6분의 42 = 7. 그래서 나는 4 지불 일 1.

    어쨌든 나는 모델 절을 사용 = schedid 예상 모델 절 :

    select schedid, to_char(duedate,'dd-mm-yyyy') duedate, expected, i paymentnum 
    from paymentscheduletable 
    model 
    partition by (schedid) 
    dimension by (1 i) 
    measures (
        startdate duedate 
    , paymentamt expected 
    , term 
    , frequency) 
    rules 
    (expected[for i from 1 to term[1]/frequency[1] increment 1] 
        = nvl(expected[cv()-1],0) + expected[1] 
    , duedate[for i from 1 to term[1]/frequency[1] increment 1] 
        = add_months(duedate[1], (cv(i)-1) * frequency[1]) 
    ) 
    order by schedid,i; 
    

    이 출력 :

    SCHEDID DUEDATE  EXPECTED PAYMENTNUM 
    ---------- ---------- ---------- ---------- 
         1 05-01-2003  1000   1 
         1 05-01-2004  2000   2 
         1 05-01-2005  3000   3 
         1 05-01-2006  4000   4 
         2 20-12-2008   25   1 
         2 20-06-2009   50   2 
         2 20-12-2009   75   3 
         2 20-06-2010  100   4 
         2 20-12-2010  125   5 
         2 20-06-2011  150   6 
         2 20-12-2011  175   7 
    
    
    11 rows selected. 
    
    +0

    당신은 SchedID 1에 대해 옳았습니다. 질문의 예는 5가 아닌 4 회 지불해야합니다. 나는 그것을 바꿀 것입니다. – witttness

    관련 문제