Pergunta

Eu tenho uma tabela como esta (Oracle, 10)

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

O que eu preciso é nova tabela agrupados por ordem Conta por asc Conta e Bookdate asc com um campo de execução total, como este:

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

Existe uma maneira simples de fazê-lo?

Agradecemos antecipadamente.

Foi útil?

Solução

Você realmente precisa da tabela extra?

Você pode obter os dados que você precisa com uma consulta simples, que você pode obviamente criar como uma visão, se você quer que ele apareça como uma tabela.

Isto fará você os dados que você está procurando:

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

Isto irá criar uma visão para mostrar a você os dados como se fosse uma tabela:

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

Se você realmente precisa da mesa, você quer dizer que você precisa constantemente atualizado? ou apenas um fora? Obviamente, se ele é um fora de você pode apenas "criar tabela como selecionar" usando a consulta acima.

Test dados que usei é:

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;

edit:

esqueceu de acrescentar; você especificou que queria a tabela a ser ordenado - isso não faz muito sentido, e me faz pensar que você realmente quer dizer que você queria a consulta / vista - ordenação é um resultado da consulta que você executar, não é algo que está em inherant a mesa (ignorando Tabelas Índice organizado e afins).

Outras dicas

Vou começar com este importante caveate: Não criar uma tabela para armazenar esses dados. Quando você fizer isso você vai achar que você precisa para mantê-lo, que vai se tornar uma dor de cabeça sem fim. Escrever uma exibição para retornar a coluna extra se você quiser fazer isso. Se você está trabalhando com um armazém de dados, em seguida, talvez você faria algo como isso, mas mesmo assim errar do lado de uma vista a menos que você simplesmente não pode obter o desempenho que você precisa com índices, hardware decente, etc.

Aqui está uma consulta que irá retornar as linhas da maneira que você precisar deles.

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

Outra solução possível é:

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

Test-los tanto para o desempenho e ver o que funciona melhor para você. Além disso, eu não exaustivamente testado para além do exemplo que você deu, por isso não deixe de testar alguns casos extremos.

usar o Google Analytics, assim como em sua última pergunta:

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
/

saída:

   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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top