programing

테이블의 그룹화된 레코드별 실행 총계

bestprogram 2023. 7. 21. 21:45

테이블의 그룹화된 레코드별 실행 총계

저는 이런 테이블이 있습니다(오라클, 10)

Account     Bookdate     Amount
      1     20080101        100
      1     20080102        101
      2     20080102        200
      1     20080103       -200
...

제가 필요한 것은 계정 순서별로 그룹화된 새 테이블과 다음과 같은 총 필드가 있는 예약 날짜별로 그룹화된 새 테이블입니다.

Account     Bookdate     Amount     Running_total
      1     20080101        100               100
      1     20080102        101               201
      1     20080103       -200                 1
      2     20080102        200               200
...

간단한 방법이 있습니까?

잘 부탁드립니다.

당신은 여분의 테이블이 정말 필요합니까?

간단한 쿼리를 사용하여 필요한 데이터를 가져올 수 있습니다. 테이블처럼 표시하려면 이 데이터를 보기로 만들 수 있습니다.

그러면 다음과 같은 데이터가 제공됩니다.

select 
    account, bookdate, amount, 
    sum(amount) over (partition by account order by bookdate) running_total
from t
/

그러면 데이터가 테이블인 것처럼 표시되는 보기가 생성됩니다.

create or replace view t2
as
select 
    account, bookdate, amount, 
    sum(amount) over (partition by account order by bookdate) running_total 
from t
/

만약 당신이 정말로 테이블이 필요하다면, 당신은 그것을 계속해서 업데이트가 필요하다는 것을 의미합니까?아니면 그냥 하나?분명히 만약 그것이 오프라면, 당신은 위의 쿼리를 사용하여 "선택한 대로 테이블을 만들" 수 있습니다.

제가 사용한 테스트 데이터:

create table t(account number, bookdate date, amount number);

insert into t(account, bookdate, amount) values (1, to_date('20080101', 'yyyymmdd'), 100);

insert into t(account, bookdate, amount) values (1, to_date('20080102', 'yyyymmdd'), 101);

insert into t(account, bookdate, amount) values (1, to_date('20080103', 'yyyymmdd'), -200);

insert into t(account, bookdate, amount) values (2, to_date('20080102', 'yyyymmdd'), 200);

commit;

편집:

추가하는 것을 잊었습니다. 테이블을 주문하도록 지정했습니다. 이것은 정말로 의미가 없으며 쿼리/뷰를 원했다는 것을 의미합니다. 주문은 테이블에서 상속되는 것이 아니라 실행하는 쿼리의 결과입니다(Index Organized Tables 등을 무시함).

먼저 매우 중요한 주의사항을 말씀드리겠습니다. 이 데이터를 저장할 테이블을 만들지 마십시오.그렇게 할 때 당신은 그것을 유지할 필요가 있다는 것을 알게 될 것이고 이것은 끝없는 두통이 될 것입니다.원하는 경우 추가 열을 반환하는 보기를 작성합니다.데이터 웨어하우스를 사용하는 경우에는 이러한 작업을 수행할 수 있지만 인덱스, 적절한 하드웨어 등에서 필요한 성능을 얻을 수 없는 경우를 제외하고는 뷰 측면에서 오류가 발생할 수 있습니다.

다음은 행을 필요한 방식으로 반환하는 쿼리입니다.

SELECT
    Account,
    Bookdate,
    Amount,
    (
        SELECT SUM(Amount)
        FROM My_Table T2
        WHERE T2.Account = T1.Account
          AND T2.Bookdate <= T1.Bookdate
    ) AS Running_Total
FROM
    My_Table T1

또 다른 가능한 솔루션은 다음과 같습니다.

SELECT
    T1.Account,
    T1.Bookdate,
    T1.Amount,
    SUM(T2.Amount)
FROM
    My_Table T1
LEFT OUTER JOIN My_Table T2 ON
    T2.Account = T1.Account AND
    T2.Bookdate <= T1.Bookdate
GROUP BY
    T1.Account,
    T1.Bookdate,
    T1.Amount

둘 다 성능을 테스트하고 어느 것이 더 효과적인지 확인합니다.또한, 저는 당신이 제시한 예시 이상으로 그것들을 철저하게 테스트하지 않았으므로, 몇 가지 엣지 케이스를 테스트하도록 하세요.

마지막 질문과 마찬가지로 분석 기능을 사용합니다.

create table accounts
( account number(10)
, bookdate date 
, amount   number(10)
);

delete accounts;

insert into accounts values (1,to_date('20080101','yyyymmdd'),100);
insert into accounts values (1,to_date('20080102','yyyymmdd'),101);
insert into accounts values (2,to_date('20080102','yyyymmdd'),200);
insert into accounts values (1,to_date('20080103','yyyymmdd'),-200);

commit;

select account
,      bookdate 
,      amount
,      sum(amount) over (partition by account order by bookdate asc) running_total
from accounts
order by account,bookdate asc
/

출력:

   ACCOUNT BOOKDATE     AMOUNT RUNNING_TOTAL
---------- -------- ---------- -------------
         1 01-01-08        100           100
         1 02-01-08        101           201
         1 03-01-08       -200             1
         2 02-01-08        200           200

언급URL : https://stackoverflow.com/questions/439138/running-total-by-grouped-records-in-table