Question

J'ai une table comme celle-ci (Oracle, 10)

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

Ce dont j'ai besoin, c’est d’une nouvelle table groupée par ordre de compte, par compte, asc et compte, et Bookdate, asc avec un champ de total cumulé, comme ceci:

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

Existe-t-il un moyen simple de le faire?

Merci d'avance.

Était-ce utile?

La solution

Avez-vous vraiment besoin de la table supplémentaire?

Vous pouvez obtenir les données dont vous avez besoin avec une requête simple, que vous pouvez évidemment créer en tant que vue si vous souhaitez qu'elle apparaisse comme une table.

Cela vous donnera les données que vous recherchez:

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

Ceci créera une vue pour vous montrer les données comme s'il s'agissait d'un tableau:

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

Si vous avez vraiment besoin de la table, voulez-vous dire que vous avez besoin de la mettre à jour en permanence? ou juste un seul? Évidemment, si c'est un cas isolé, vous pouvez simplement "créer une table en tant que sélectionner". en utilisant la requête ci-dessus.

Les données de test que j'ai utilisées sont:

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;

modifier:

a oublié d'ajouter; vous avez indiqué que vous vouliez que la table soit ordonnée - cela n'a pas vraiment de sens et me fait penser que vous vouliez vraiment dire que vous vouliez la requête / vue - l'ordre est le résultat de la requête que vous exécutez, pas quelque chose qui est inhérent à la table (en ignorant les tables organisées par index, etc.).

Autres conseils

Je commencerai par cet important problème: ne créez PAS de table pour stocker ces données. Quand vous le ferez, vous constaterez que vous devez le maintenir, ce qui deviendra un mal de tête sans fin. Ecrivez une vue pour renvoyer la colonne supplémentaire si vous voulez le faire. Si vous travaillez avec un entrepôt de données, alors peut-être vous feriez quelque chose comme ceci, mais même dans ce cas, vous vous tromperiez du côté d'une vue, à moins que vous n'obteniez tout simplement pas les performances dont vous avez besoin avec les index, matériel convenable, etc.

Voici une requête qui renvoie les lignes de la manière dont vous en avez besoin.

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

Une autre solution possible est la suivante:

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

Testez leurs performances et voyez ce qui vous convient le mieux. De plus, je ne les ai pas complètement testés au-delà de l'exemple que vous avez donné. Veillez donc à tester certains cas critiques.

Utilisez l'analyse, comme dans votre dernière question:

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
/

sortie:

   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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top