문제

나는 이와 같은 테이블이있다 (Oracle, 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;

편집하다:

추가하는 것을 잊었습니다. 당신은 당신이 테이블을 주문하기를 원한다고 지정했습니다 - 이것은 실제로 의미가 없으며, 당신이 쿼리/뷰를 원한다고 생각하게 만듭니다. 주문은 실행 한 쿼리의 결과입니다. 테이블 (인덱스 조직 테이블 등을 무시).

다른 팁

이 매우 중요한 경고로 시작하겠습니다.이 데이터를 보유 할 테이블을 만들지 마십시오. 당신이 할 때 당신은 끝없는 두통이 될 것을 유지해야한다는 것을 알게 될 것입니다. 원하는 경우 추가 열을 반환하려면보기를 작성하십시오. 데이터웨어 하우스와 함께 일하는 경우 아마도 당신은 이와 같은 일을 할 것이지만, 심지어 인덱스, 괜찮은 하드웨어 등으로 필요한 성능을 얻을 수 없다면보기 측면에서 오류가 발생합니다.

여기에 필요한 방식으로 행을 반환하는 쿼리가 있습니다.

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top