2010-09-24 8 views
9

Ich habe eine Tabelle wie diese:SQLite: Akkumulator (sum) Spalte in einer SELECT-Anweisung

SELECT Wert aus Tabelle;

value 
1 
3 
13 
1 
5 

würde Ich mag einen Akkumulator Spalte hinzuzufügen, so dass ich dieses Ergebnis haben:

value accumulated 
1  1 
3  4 
13  17 
1  18 
5  23 

Wie kann ich das tun? Wie heißt eigentlich, was ich machen möchte? Dank

Antwort

11

versuchen auf diese Weise:

select value, 
(select sum(t2.value) from table t2 where t2.id <= t1.id) as accumulated 
from table t1 

aber wenn es nicht auf der Datenbank arbeiten, nur um von

select value, 
(select sum(t2.value) from table t2 where t2.id <= t1.id order by id) as accumulated 
from table t1 
order by id 

dies auf ein Orakel funktioniert etwas hinzufügen;), aber es sollte auf eine sqlite too

+0

Hätte es an einer Tabelle ohne ID zum Ordnen funktioniert (oder nach einem anderen Kriterium, ohne Möglichkeit eines strikten moala

+0

Sie können dies mit einer analytischen Abfrage tun Wenn Sie Oracle verwenden, werden keine Self Joins benötigt, siehe http://www.orafaq.com/node/55. Leider unterstützt sqlte keine analytischen Abfragen. – TTT

1

Die Operation wird als laufende Summe bezeichnet. SQLite unterstützt es nicht so, wie es ist, aber es gibt Möglichkeiten, es zum Laufen zu bringen. Einer ist genau wie Sebastian Brózda gepostet. Ein anderes Ich habe here in einer anderen Frage beschrieben.

+0

oder "läuft insgesamt". Danke. – moala

1

Hier ist eine Methode zum Erstellen einer laufenden Summe ohne die Ineffizienz der Summierung aller vorherigen Zeilen. (Ich weiß, diese Frage 6 Jahre alt ist, aber es ist eine der ersten Google-Einträge für SQLite laufende Summe.)

create table t1 (value integer, accumulated integer, id integer primary key); 
insert into t1 (value) values (1); 
insert into t1 (value) values (3); 
insert into t1 (value) values (13); 
insert into t1 (value) values (1); 
insert into t1 (value) values (5); 

UPDATE 
    t1 
SET 
    accumulated = ifnull(
    (
     SELECT 
      ifnull(accumulated,0) 
     FROM 
      t1 ROWPRIOR 
     WHERE 
      ROWPRIOR.id = (t1.id -1)),0) + value; 


.headers on 
select * from t1; 
value|accumulated|id 
1|1|1 
3|4|2 
13|17|3 
1|18|4 
5|23|5 

Dies sollte nur einmal ausgeführt werden, nachdem alle Werte importieren. Oder setzen Sie die akkumulierte Spalte auf alle Nullen, bevor Sie sie erneut ausführen.

+0

Das funktioniert super. Ich nahm eine große Tabelle, die anderen Akkumulationsmustern widerstand, und wählte (mit der Reihenfolge nach) die relevanten Felder in eine temporäre Tabelle mit einem Autoinkrement und verwendete dann dieses Muster, indem ich eine "t1.itemId = ROWPRIOR.itemId" zu der Where hinzufügte Klausel. Jedes Mal, wenn ein neuer Gegenstand getroffen wird, beginnt die Akkumulation erneut. Schneiden Sie eine mehrstündige Laufzeit auf vielleicht 15 Sekunden. – chad