Frage

Ich habe eine Tabelle wie diese (Oracle, 10)

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

Was ich brauche, ist neue Tabelle nach Konto, um nach Konto asc und Bookdate asc mit einem laufenden Gesamtfeld gruppiert, wie folgt aus:

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

Gibt es eine einfache Möglichkeit, es zu tun?

Vielen Dank im Voraus.

War es hilfreich?

Lösung

Haben Sie wirklich brauchen die zusätzliche Tabelle?

Sie können diese Daten erhalten Sie mit einer einfachen Abfrage benötigen, die Sie als Ansicht offensichtlich schaffen können, wenn man es wie eine Tabelle angezeigt werden sollen.

Diese erhalten Sie die Daten, die Sie suchen:

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

Dies wird eine Ansicht zu erstellen, um die Daten zu zeigen, als ob es sich um eine Tabelle waren:

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

Wenn Sie wirklich die Tabelle benötigen, meinen Sie, dass Sie es ständig aktualisiert müssen? oder einfach nur ein einmaliger? Natürlich, wenn es sich um eine aus ist kann man einfach „create table as select“, um die obige Abfrage verwendet wird.

Die Testdaten I verwendet wird:

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:

hat vergessen, hinzuzufügen; Sie angegeben haben, dass Sie die Tabelle bestellt werden wollte - dieses Gefühl nicht wirklich machen, und lässt mich denken, dass Sie wirklich bedeuten, dass Sie die Abfrage / Ansicht wollte - Bestellung ist ein Ergebnis der Abfrage Sie, nicht etwas auszuführen, die inherant ist in die Tabelle (Tabellen Index Organized und dergleichen zu ignorieren).

Andere Tipps

Ich werde mit dieser sehr wichtigen caveate beginnen: Erstellen Sie keine Tabelle, um diese Daten zu halten. Wenn Sie tun, werden Sie feststellen, dass Sie es zu halten brauchen, die eine nie endende Kopfschmerzen werden wird. Schreiben Sie eine Ansicht, die die zusätzliche Spalte zurück, wenn Sie das tun wollen. Wenn Sie mit einem Data-Warehouse arbeiten dann vielleicht Sie würde so etwas tun, aber auch dann auf der Seite einer Ansicht irren, wenn Sie einfach nicht die Leistung erhalten können, die Sie mit Indizes benötigen, anständige Hardware, etc.

Hier ist eine Abfrage, die die Reihen den Weg zurückkehren, die sie gebraucht werden.

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

Eine andere mögliche Lösung ist:

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

Testen Sie sowohl für die Leistung und sehen, welche für Sie besser funktioniert. Auch ich habe nicht gründlich getestet sie über das Beispiel, das Sie gab, so sicher sein, einige Grenzfälle zu prüfen.

Mit Analysen, wie in Ihrer letzten Frage:

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
/

Ausgabe:

   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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top