2013-01-18 2 views
1

은 우리가 테이블빌드 회계 흔적 균형 보고서 성능 문제

create table jour_entries 
(jseq number, 
    j_date date, 
    Eseq number, 
    account_no varchar2(32), 
    debit number, 
    credit number, 
    note varchar2(256)); 

방법 SQL 재판 균형을위한 최적의 성능 보고서를 구축하기 위해 수행 항목 저널이 있다고 가정? 보고서 열은

  • 입니다. account_number는 계좌 번호입니다.

  • debit_within_month는 (또는 주어진 날짜는 현재 월에있는 경우 현재 날짜까지)

  • credit_within_month 그 달의 마지막까지 특정 달의 1 일부터 시작 ACCOUNT_NUMBER 관련된 모든 차변의 합계입니다 : 합 매월 1 일부터 해당 월 말까지 (또는 해당 월이 현재 달인 경우 당일까지) account_number와 관련된 모든 크레딧의 금액입니다.

  • debit_till_this_day :은 account_number와 관련된 모든 금액의 누계액입니다. 주어진 날짜 (1 일부터 1 일까지).

  • credit_till_this_day : account_number와 관련된 모든 크레딧의 누적 합계입니다 (주어진 날짜의 1 월 1 일부터 현재 날짜까지).


나는이 선택 시도 :

select account_number 
     , debit_within_month 
     , credit_within_month 
     , debit_till_this_day 
     , credit_till_this_day 
from jour_entries j, 
    (select account_number, sum(debit) debit_within_month, 
         sum(credit) credit_within_month 
       from jour_entries 
       where j_date between trunc(given_date, 'month') and given_date 
       group by account_number 
    ) j1, 
    (select account_number, sum(debit) debit_till_this_day, 
         sum(credit) credit_till_this_day 
       from jour_entries 
       where j_date between trunc(given_date, 'year') and given_date 
       group by account_number 
    ) j2 
wherer j.account_number = j1.account_number 
and j.account_number = j2.account_number 

하지만 최적의 성능을 위해 (아마도 분석 함수를 사용하여) 다른 솔루션을 찾고 있어요. 나는 당신의 질문을 이해 해요 경우

+0

이미 시도한 것은 무엇입니까? – a1ex07

+0

성능을 제외하면 주어진 날짜가 현재 달에없는 경우 솔루션에서 월별 합계에 대한 올바른 결과를 제공하지 않습니다. 또한 TIL CURRENT 총계에 대한 논리도 잘못되었습니다. – APC

+0

2012 년 6 월에 사용자가 '31-may-2012 '날짜를 입력하면 보고서는 각 account_number에 대해 모든 거래 (직불, 신용)가 발생할 수 있으며 2012 년 시작에서 끝날 때까지 모든 거래가 발생합니다 5 월의. –

답변

0

는 당신을 위해 작동합니다 같은 것을 같은 소리 :

SELECT JE.Account_no as Account__Number, 
    SUM(JE2.debit) as Debit_Within_Month, 
    SUM(JE2.credit) as Credit_Within_Month, 
    SUM(JE.debit) as Debit_Till_This_Day, 
    SUM(JE.credit) as Credit_Till_This_Day 
FROM Jour_Entries JE 
    LEFT JOIN (
     SELECT jseq, Account_No, Debit, Credit 
     FROM Jour_Entries 
     WHERE to_char(j_date, 'YYYY') = 2013 AND to_char(j_date, 'mm') = 2 
    ) JE2 ON JE.jseq = JE2.jseq 
WHERE to_char(j_date, 'YYYY') = 2013 
GROUP BY JE.Account_no 

가 여기에 sql fiddle입니다.

행운을 빈다.

2

given_month를 나타 내기 위해 SQL * Plus 대체 변수 구문을 사용합니다. 실제로 사용하는 클라이언트에 관계없이이 값을 변경해야합니다. 날짜에 적용

select account_number 
     , sum (case when J_date between trunc(&given_date, 'mm') 
            and least(sysdate, last_day(&given_date)) 
      then debit else 0 end) as debit_within_month 
     , sum (case when J_date between trunc(&given_date, 'mm') 
            and least(sysdate, last_day(&given_date)) 
      then credit else 0 end) as credit_within_month 
     , sum (case when J_date between trunc(&given_date, 'yyyy') and sysdate) 
       then debit else 0 end) as debit_til_this_day 
     , sum (case when J_date between trunc(&given_date, 'yyyy') and sysdate) 
       then credit else 0 end) as credit_til_this_day 
from jour_entries 
group by account_number 

설명

  • trunc()는 지정된 형식 마스크로 자릅니다. 따라서 trunc(sysdate, 'mm')은 첫 번째 달을주고 'yyyy'마스크는 첫 해를 나타냅니다.
  • last_day()은 해당 월의 마지막 날을 나타냅니다.
+1

이것이 방법입니다. 평가판 잔액의 경우 원장 테이블의 모든 행이 필요합니다. 이는 대차 대조표 항목이 현재까지의 잔액이기 때문입니다. 모든 행을 필요로한다는 것은 인덱스 검색보다 전체 스캔이 더 효율적이라는 것을 의미하며 유일한 옵션은 여기에 제안 된대로 한 번만 테이블을 스캔하려고하는 것입니다. –