Pergunta

What is the best way to maintain a "cumulative sum" of a particular data column in SQLite? I have found several examples online, but I am not 100% certain how I might integrate these approaches into my ContentProvider.

In previous applications, I have tried to maintain cumulative data myself, updating the data each time I insert new data into the table. For example, in the sample code below, every time I would add a new record with a value score, I would then manually update the value of cumulative_score based on its value in the previous row.

_id   score   cumulative_score
1     100     100
2     50      150
3     25      175
4     25      200
5     10      210

However, this is far from ideal and becomes very messy when handling tables with many columns. Is there a way to somehow automate the process of updating cumulative data each time I insert/update records in my table? How might I integrate this into my ContentProvider implementation?

I know there must be a way to do this... I just don't know how. Thanks!

Foi útil?

Solução

Probably the easiest way is with a SQLite trigger. That is the closest I know of to "automation". Just have an insert trigger that takes the previous cumulative sum, adds the current score and stores it in the new row's cumulative sum. Something like this (assuming _id is the column you are ordering on):

CREATE TRIGGER calc_cumulative_score AFTER INSERT ON tablename FOR EACH ROW
BEGIN
    UPDATE tablename SET cumulative_score =
        (SELECT cumulative_score
         FROM tablename
         WHERE _id = (SELECT MAX(_id) FROM tablename))
        + new.score
    WHERE _id = new._id;
END

Making sure that the trigger and the original insert are in the same transaction. For arbitrary updates of the score column, you would have to have to implement a recursive trigger that somehow finds the next highest id (maybe by selecting by the min id in the set of rows with an id greater than the current one) and updates its cumulative sum.

If you are opposed to using triggers, you can do more or less the same thing in the ContentProvider in the insert and update methods manually, though since you're pretty much locked into SQLite on Android, I don't see much reason not to use triggers.

I assume you are wanting to do this as an optimization, as otherwise you could just calculate the sum on demand (O(n) vs O(1), so you'd have to consider how big n might get, and how often you need the sums).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top