Значение по умолчанию для Postgres - это разница двух записей - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть таблица postgres со столбцами: id, text, timestamp, diff id генерируется автоматически, текст вставляется, timestamp является значением по умолчанию, и diff должен быть разницей между отметкой времени текущей записи и отметкой времени предыдущей записи (prev by id) если предыдущий день совпадает с фактическим, в противном случае он должен быть равен 0. Таким образом, все столбцы генерируются автоматически при вставке текста.Знаете ли вы какой-нибудь способ сделать этот diff по умолчанию выражением или чем-то еще?Я новичок в sql.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Я бы пошел за VIEW

CREATE OR REPLACE VIEW v_tbl AS
SELECT id,
       txt,
       tstamp,
       coalesce (  extract ( epoch FROM tstamp - LAG(tstamp)
        OVER(PARTITION BY date_trunc('day',tstamp) ORDER BY id)),0)
 FROM tbl;

Демо

0 голосов
/ 21 декабря 2018

Для этого вы можете использовать триггер:

demo: db <> fiddle

CREATE TABLE tbl (
    id int,
    ts timestamp DEFAULT now(),                                     -- 1
    diff float                                                      -- 2
);

CREATE FUNCTION set_ts_diff() RETURNS trigger AS $$
    DECLARE
        _last_ts timestamp;
    BEGIN
        SELECT COALESCE(MAX(ts), NEW.ts) FROM tbl INTO _last_ts;    -- 3

        IF (NEW.ts::date = _last_ts::date) THEN                     -- 4
            NEW.diff := EXTRACT(EPOCH FROM NEW.ts - _last_ts);      -- 5
        ELSE
            NEW.diff := 0;
        END IF;

        RETURN NEW;
    END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tr_set_ts_diff BEFORE INSERT ON tbl                  -- 6
    FOR EACH ROW EXECUTE PROCEDURE set_ts_diff();
  1. Создайте свою таблицу.ts получает текущую метку времени (now()) по умолчанию.
  2. diff будет использоваться как разница в секундах.Поскольку две вставки могут быть сделаны за одну секунду, помогает тип float.Другим способом может быть тип interval, который является типом по умолчанию для вычитаний меток времени (см. Пункт 5)
  3. Для триггера требуется функция триггера, чтобы знать, что делать после запуска события.В этой функции мы получаем последний ts, сохраненный в tbl ранее.Если строки не существует, берется текущий ts (NEW - текущая строка для вставки) с помощью COALESCE
  4. Затем проверьте, совпадают ли последний и текущий tsдата (проверяется путем приведения обеих меток времени к date).
  5. Если это так, вычислите разницу, которая приводит к типу interval.Чтобы получить секунды из interval, используйте EXTRACT(EPOCH FROM ...).
  6. Создайте триггер: перед сохранением новой строки (ON BEFORE INSERT) выполните функцию триггера и установите столбец NEW.diff.

Примечание:

Вам едва следует сохранять данные, которые можно рассчитать позже.Разницу между двумя временными метками можно рассчитать с помощью оконной функции LAG , которая переводит значение предыдущей строки в текущую ( demo ):

SELECT
    ts,
    EXTRACT(EPOCH FROM ts - lag(ts) OVER (ORDER BY ts)) as diff
FROM
    tbl;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...