将 table 列保留在另一个 table 中列的最早相关值
Keep a table column at the earliest related value of a column in another table
我有两个相关的 table。让我们用以下列来称呼它们 event_types
和 occurrences
:
event_types
-------------
id VARCHAR(30)
name VARCHAR(50)
first_event Timestamp
和
occurrences
-------------
id VARCHAR(30)
event_type_id VARCHAR(30)
timestamp Timestamp
postal_number Integer
city VARCHAR(50)
street VARCHAR(50)
我想添加一个触发器来更新 first_event
,以防新的 occurrence
出现较早的 timestamp
。
用例:原因是我需要根据 first_event
上的条件频繁查询此 event_type
table 并按此字段对其进行排序以获得一段时间内的那些帧.
我试过这样的东西:
CREATE OR REPLACE FUNCTION set_to_minimum_time() RETURNS TRIGGER AS
$$
BEGIN
IF NEW.timestamp < SELECT first_event from event_types where id=NEW.event_type_id THEN
UPDATE event_types
SET first_event = NEW.timestamp
WHERE id = NEW.event_type_id
END IF
END;
$$
LANGUAGE PLPGSQL;
CREATE TRIGGER after_trigger_time_updater
AFTER INSERT OR UPDATE OR DELETE
ON occurrences
FOR EACH ROW
EXECUTE PROCEDURE set_to_minimum_time();
这已经失败了,因为 if 子句中的 select 语句有语法错误。那么如何通过触发器实现这样的更新呢?
我正在使用 Postgres > 9.5 和 10。
进一步说明:此类更新不会经常出现。
您可以通过在 SELECT
语句两边加上括号来避免语法错误。
但是你又犯了一个错误:你定义了触发器ON DELETE
,在这种情况下没有NEW
记录。无论如何,拥有这个触发器 ON DELETE
是没有意义的,是吗?
触发器中的SQL语句可以更简单:
UPDATE event_types
SET first_event = NEW.timestamp
WHERE id = NEW.event_type_id
AND first_event < NEW.timestamp;
在同一语句中执行检查。
在 Laurenz Albe 的帮助下我的最终解决方案:
CREATE OR REPLACE FUNCTION maybe_update_event_type_time() RETURNS TRIGGER AS $maybe_update_event_type_time$
BEGIN
UPDATE event_types t
SET t.first_event = NEW.timestamp
WHERE t.id = NEW.event_type_id
AND t.first_event > NEW.timestamp;
RETURN NULL;
END;
$maybe_update_event_type_time$ LANGUAGE PLPGSQL;
CREATE TRIGGER after_trigger_anomaly_time_updater
AFTER INSERT OR UPDATE
ON occurrences
FOR EACH ROW
EXECUTE PROCEDURE maybe_update_event_type_time();
我有两个相关的 table。让我们用以下列来称呼它们 event_types
和 occurrences
:
event_types
-------------
id VARCHAR(30)
name VARCHAR(50)
first_event Timestamp
和
occurrences
-------------
id VARCHAR(30)
event_type_id VARCHAR(30)
timestamp Timestamp
postal_number Integer
city VARCHAR(50)
street VARCHAR(50)
我想添加一个触发器来更新 first_event
,以防新的 occurrence
出现较早的 timestamp
。
用例:原因是我需要根据 first_event
上的条件频繁查询此 event_type
table 并按此字段对其进行排序以获得一段时间内的那些帧.
我试过这样的东西:
CREATE OR REPLACE FUNCTION set_to_minimum_time() RETURNS TRIGGER AS
$$
BEGIN
IF NEW.timestamp < SELECT first_event from event_types where id=NEW.event_type_id THEN
UPDATE event_types
SET first_event = NEW.timestamp
WHERE id = NEW.event_type_id
END IF
END;
$$
LANGUAGE PLPGSQL;
CREATE TRIGGER after_trigger_time_updater
AFTER INSERT OR UPDATE OR DELETE
ON occurrences
FOR EACH ROW
EXECUTE PROCEDURE set_to_minimum_time();
这已经失败了,因为 if 子句中的 select 语句有语法错误。那么如何通过触发器实现这样的更新呢?
我正在使用 Postgres > 9.5 和 10。
进一步说明:此类更新不会经常出现。
您可以通过在 SELECT
语句两边加上括号来避免语法错误。
但是你又犯了一个错误:你定义了触发器ON DELETE
,在这种情况下没有NEW
记录。无论如何,拥有这个触发器 ON DELETE
是没有意义的,是吗?
触发器中的SQL语句可以更简单:
UPDATE event_types
SET first_event = NEW.timestamp
WHERE id = NEW.event_type_id
AND first_event < NEW.timestamp;
在同一语句中执行检查。
在 Laurenz Albe 的帮助下我的最终解决方案:
CREATE OR REPLACE FUNCTION maybe_update_event_type_time() RETURNS TRIGGER AS $maybe_update_event_type_time$
BEGIN
UPDATE event_types t
SET t.first_event = NEW.timestamp
WHERE t.id = NEW.event_type_id
AND t.first_event > NEW.timestamp;
RETURN NULL;
END;
$maybe_update_event_type_time$ LANGUAGE PLPGSQL;
CREATE TRIGGER after_trigger_anomaly_time_updater
AFTER INSERT OR UPDATE
ON occurrences
FOR EACH ROW
EXECUTE PROCEDURE maybe_update_event_type_time();