Android - простой / эффективный способ поддержания «накопительной суммы» для столбца SQLite - PullRequest
0 голосов
/ 15 марта 2012

Каков наилучший способ сохранить «совокупную сумму» определенного столбца данных в SQLite? Я нашел несколько примеров в Интернете, но я не уверен на 100%, как я могу интегрировать эти подходы в мой ContentProvider.

В предыдущих приложениях я пытался вести кумулятивные данные самостоятельно, обновляя данные каждый раз, когда я вставляю новые данные в таблицу. Например, в приведенном ниже примере кода каждый раз, когда я добавляю новую запись со значением score, я вручную обновляю значение cumulative_score на основе его значения в предыдущей строке.

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

Однако это далеко от идеала и становится очень грязным при работе с таблицами со многими столбцами. Есть ли способ как-то автоматизировать процесс обновления накопительных данных каждый раз, когда я вставляю / обновляю записи в своей таблице? Как я могу интегрировать это в мою ContentProvider реализацию?

Я знаю, что должен быть способ сделать это ... Я просто не знаю как. Спасибо!

1 Ответ

3 голосов
/ 15 апреля 2012

Вероятно, самый простой способ - использовать триггер SQLite.Это самое близкое, что я знаю о "автоматизации".Просто используйте триггер вставки, который берет предыдущую накопленную сумму, добавляет текущий счет и сохраняет его в накопленной сумме нового ряда.Примерно так (при условии, что _id - это столбец, по которому вы заказываете):

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

Убедитесь, что триггер и исходная вставка находятся в одной транзакции.Для произвольных обновлений столбца score вам потребуется реализовать рекурсивный триггер, который каким-то образом находит следующий по величине идентификатор (возможно, путем выбора по идентификатору min в наборе строк с идентификатором, превышающим текущий), иобновляет свою накопленную сумму.

Если вы против использования триггеров, вы можете сделать более или менее то же самое в ContentProvider в методах insert и update вручную, хотя вы в значительной степени заблокированы в SQLite на Android.Я не вижу особых причин не использовать триггеры.

Я предполагаю, что вы хотите сделать это как оптимизацию, так как в противном случае вы могли бы просто рассчитать сумму по требованию (O(n) против O(1), так что вам нужно будет подумать, насколько большой n можетполучить, и как часто вам нужны суммы).

...