Сначала, если вы хотите пойти по этому пути, начните с документации PostgreSQL по программированию сервера, а затем вернитесь с вопросом, основанным на том, что вы пробовали. Вы все равно захотите ознакомиться с этой областью, потому что в зависимости от того, что вы делаете ....
Теперь, при условии, что ваши данные все вставлены и не обновлены, я бы не сохранил бы эту информацию непосредственно в вашей базе данных. Если это небольшой объем информации, вы все равно получите индексное сканирование, и если вы возвращаете небольшой набор результатов, вы сможете быстро его вычислить.
Вместо этого я бы сделал это: ваш столбец last_update должен быть внешним ключом той же таблицы. Предположим, ваш стол выглядит так:
CREATE TABLE hits (
id bigserial primary key,
number_hits bigint not null,
last_update_id bigint references hits(id),
....
);
Тогда я бы создал следующие функции. Обратите внимание на предостережения ниже.
CREATE FUNCTION last_update(hits) RETURNS hits IMMUTABLE LANGUAGE SQL AS $$
SELECT * FROM hits WHERE id = $1.last_update_id;
$$;
Эта функция позволяет при небольшом наборе результатов переходить к последней записи обновления. Обратите внимание, что неизменное обозначение здесь безопасно только в том случае, если вы гарантируете, что в таблице совпадений нет обновлений или удалений. Если вы сделаете это, то вы должны изменить его на стабильный, и вы потеряете способность индексировать вывод. Если вы даете эту гарантию, а затем должны выполнить обновление, то вы ДОЛЖНЫ перестроить все индексы, которые используют это (переиндексация обращений к таблице), и это может занять некоторое время ....
Оттуда мы можем:
CREATE FUNCTION growth(hits) RETURNS numeric immutable language sql as $$
SELECT CASE WHEN ($1.last_update).number_hits = 0 THEN NULL
ELSE $1.number_hits / ($1.last_update).number_hits
END;
$$;
Тогда мы можем:
SELECT h.growth -- or alternatively growth(h)
FROM hits
WHERE id = 12345;
И он автоматически его вычислит. Если мы хотим искать по росту, мы можем проиндексировать вывод:
CREATE INDEX hits_growth_idx ON hits (growth(hits));
Это будет предварительно рассчитано для целей поиска. Таким образом, если вы хотите сделать:
SELECT * FROM hits WHERE growth = 1;
Может использоваться сканирование индекса по заранее заданным значениям.
Конечно, вы можете использовать те же методы для предварительного расчета и хранения, но этот подход более гибкий, и если вам приходится работать с большим набором результатов, вы всегда можете самостоятельно объединиться один раз и рассчитать таким образом, минуя свои функции .