2010-09-24 74 views
9

Tengo una tabla como la siguiente:SQLite: acumulador (suma) de columna en una instrucción SELECT

valor SELECT FROM tabla;

value 
1 
3 
13 
1 
5 

Me gustaría añadir una columna de acumulador, de manera que tengo este resultado:

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

¿Cómo puedo hacer esto? ¿Cuál es el verdadero nombre de lo que quiero hacer? Gracias

Respuesta

11

tratar de esta manera:

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

pero si no va a funcionar en su base de datos, sólo tiene que añadir ordenado por algo

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 

esto funciona en un oráculo;) pero debería en una sqlite también

+0

Si hubiera funcionado en una tabla sin identificación para ordenar (u ordenando después de otro criterio, sin posibilidad de estricta moala

+0

Puede hacer esto con una consulta analítica cuando usa Oracle, no es necesario unir uno mismo, vea http://www.orafaq.com/node/55. Tristemente sqlte no admite consultas analíticas. – TTT

1

La operación se denomina suma en ejecución. SQLite no lo admite tal cual, pero hay formas de hacerlo funcionar. Uno es justo como Sebastian Brózda publicó. Otro que detallé here en otra pregunta.

+0

o "total acumulado". Gracias. – moala

1

Aquí hay un método para crear un total acumulado sin la ineficacia de sumar todas las filas anteriores. (Sé que esta pregunta es de 6 años de edad, pero es una de las primeras entradas de Google para ejecución total SQLite.)

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 

Esto sólo se debe ejecutar una vez después de la importación de todos los valores. O bien, establezca la columna acumulada en todos los valores nulos antes de volver a ejecutar.

+0

Esto funciona muy bien. Tomé una tabla grande que resistía otros patrones de acumulación y seleccioné (con el pedido de) los campos relevantes en una tabla temporal con un autoincrement, y luego usé este patrón agregando un 't1.itemId = ROWPRIOR.itemId' al lugar donde cláusula. Cada vez que golpea un nuevo objeto, la acumulación comienza de nuevo. Reduzca un tiempo de ejecución de varias horas a quizás 15 segundos. – chad

Cuestiones relacionadas