SELECT DISTINCT ON (test1.f1) *
FROM test AS test1, (SELECT -1 AS f1, NULL AS f2 UNION SELECT f1, f2
FROM test ORDER BY f1) AS test2 WHERE (test1.f1-test2.f1)>0 ORDER BY test1.f1, (test1.f1-test2.f1) ASC;
Po pierwsze wyjaśnienia. kolumne id reprezentuje f1, kolumne wart f2.
No więc tak, oto zapytanie, które pozwala wyciągnąć taki ciąg złożony z rekordu + poprzednika pod pgsql'em, nawet jeżeli są dziury w id. Niestety wyrażenie DISTINCT ON nie jest częścią standartu SQL, a jak na razie nie wymyśliłem jeszcze jakby to DISTINCT ON wyeliminować. Tutaj oczywiście odpada możliwość UPDATE, ale możemy zrobić nową tabelę o innej nazwie z takimi samymi kolumnami + kolumną zm_proc:
SELECT
INTO nowa_tabela tutaj, wyliczamy, wszystkie, pola, wart1 AS wart, (((wart2-wart1)/wart1)*100)::integer AS zm_proc
FROM (SELECT DISTINCT ON (tabela1.f1) tabela1.*, tabela1.f2 AS wart1, tabela2.f2 AS wart2
FROM tabela AS tabela1, (SELECT -1 AS f1, NULL AS f2 UNION SELECT f1, f2
FROM tabela ORDER BY f1) AS tabela2 WHERE (test1.f1-test2.f1)>0 ORDER BY tabela1.f1, (tabela1.f1-tabela2.f1) ASC) AS xxx;
DROP TABLE tabela;
ALTER TABLE nowa_table RENAME TO tabela;
To powinno zadziałać, ale jak już powtarzałem tylko na pgsql'u. Rzeby to przenieść na inną bazę trzeba wyeliminować DISTINCT ON, a ja jak na razie nie mam na to pomysłu. Aha, i w głównym selekcie wszystkie pola muszą! być wyliczone, nie można ich zastąpić *.
Potem możemy sobie zrobić sekwencje, ustawić jej currval na ostatnie id z tabeli i zmienić DEFAULT na nextval('nazwa_sekwencji').
AHA - I jeżeli będziesz próbował to transakcje włącz na wypadek jakbym się mylił.