Если вы используете последнюю версию sqlite (3.25 или новее), это довольно легко сделать с помощью оконных функций.Далее предполагается, что вы упорядочиваете по столбцу имени, как в примере ввода и вывода:
CREATE TABLE example(name TEXT, value INTEGER, adj INTEGER);
INSERT INTO example VALUES('Apple',10,5);
INSERT INTO example VALUES('Ball',20,10);
INSERT INTO example VALUES('Cat',30,15);
INSERT INTO example VALUES('Dog',40,0);
INSERT INTO example VALUES('Emily',50,10);
INSERT INTO example VALUES('Frog',60,0);
INSERT INTO example VALUES('Goat',70,5);
CREATE INDEX example_idx_name ON example(name); -- Used in the window ordering
SELECT name AS "Name"
, first_value(value) OVER names + sum(adj) OVER names - adj AS "Value"
, adj AS "Adjustment"
FROM example
WINDOW names AS (ORDER BY name)
ORDER BY name;
производит:
Name Value Adjustment
---------- ---------- ----------
Apple 10 5
Ball 15 10
Cat 25 15
Dog 40 0
Emily 40 10
Frog 50 0
Goat 50 5
Теперь вместо обновления таблицы ...проблема с UPDATE
заключается в том, что строки обновляются в произвольном порядке (возможно, по rowid, но вы не должны зависеть от таких деталей реализации), поэтому вы не можете что-то сделать на основе «предыдущей» строки.Один из подходов: используйте версию вышеуказанного запроса для заполнения временной таблицы, а затем используйте ее для обновления оригинала:
CREATE TEMP TABLE staging(id INTEGER PRIMARY KEY, value INTEGER);
INSERT INTO staging
SELECT rowid, first_value(value) OVER names + sum(adj) OVER names - adj
FROM example WINDOW names AS (ORDER BY name);
UPDATE example AS e SET value = (SELECT value FROM staging AS s WHERE s.id = e.rowid);
DROP TABLE staging;
SELECT * FROM example ORDER BY name;
name value adj
---------- ---------- ----------
Apple 10 5
Ball 15 10
Cat 25 15
Dog 40 0
Emily 40 10
Frog 50 0
Goat 50 5