TimescaleDB/Postgres:插入冲突保持最大值
TimescaleDB/Postgres: INSERT ON CONFLICT KEEP MAXIMUM
我的 table 定义为:(这是一个简单的度量配置跟踪)
CREATE TABLE IF NOT EXISTS strategy_registry (
name VARCHAR NOT NULL,
symbol VARCHAR NOT NULL,
predictor_id VARCHAR NOT NULL,
params jsonb NOT NULL,
metric FLOAT NOT NULL,
PRIMARY KEY(name, symbol, predictor_id)
);
并且在插入冲突时,我想保留获得最大度量值的版本的最大度量和参数列。我正在使用 TimescaleDB (postgres 12)
INSERT INTO strategy_registry (name, symbol, predictor_id, params, metric)
VALUES ({{ name }}, {{ symbol }}, {{ predictor_id }}, {{ params }}, {{ metric }})
ON CONFLICT (name, symbol, predictor_id)
DO UPDATE SET
(metric, params) = max(existing, excluded), params of greatest `metric` column value;
您要查找的函数是 greatest(...) 而不是 max。 Max 是一个柱状函数,适用于整个行集,在本例中为 table。 Greatest 从值(或变量)列表中选择 'maximum' 值。示例:
select greatest(1,4,3,5,7,0)
returns 7. 它也可以在作业中使用,如
something = greatest(...);
我认为您无法同时处理两列。这样的事情应该有效:
INSERT INTO strategy_registry (name, symbol, predictor_id, params, metric)
VALUES ({{ name }}, {{ symbol }}, {{ predictor_id }}, {{ params }}, {{ metric }})
ON CONFLICT (name, symbol, predictor_id)
DO UPDATE
SET params = CASE
WHEN metric < EXCLUDED.metric THEN EXCLUDED.params
ELSE params
END,
metric = GREATEST(metric, EXCLUDED.metric);
我认为其他答案应该可行,但是,我想说这可能不是实现此目标的最有效方法。相反,我会在更新中使用 WHERE
子句:
ON CONFLICT (name, symbol, predictor_id) DO UPDATE SET
metric = excluded.metric, params = excluded.params
WHERE excluded.metric > metric
即使值保持不变并导致 table 膨胀和额外的工作(另外,我认为它在语义上更清晰),先前的答案也可以进行更新。
我的 table 定义为:(这是一个简单的度量配置跟踪)
CREATE TABLE IF NOT EXISTS strategy_registry (
name VARCHAR NOT NULL,
symbol VARCHAR NOT NULL,
predictor_id VARCHAR NOT NULL,
params jsonb NOT NULL,
metric FLOAT NOT NULL,
PRIMARY KEY(name, symbol, predictor_id)
);
并且在插入冲突时,我想保留获得最大度量值的版本的最大度量和参数列。我正在使用 TimescaleDB (postgres 12)
INSERT INTO strategy_registry (name, symbol, predictor_id, params, metric)
VALUES ({{ name }}, {{ symbol }}, {{ predictor_id }}, {{ params }}, {{ metric }})
ON CONFLICT (name, symbol, predictor_id)
DO UPDATE SET
(metric, params) = max(existing, excluded), params of greatest `metric` column value;
您要查找的函数是 greatest(...) 而不是 max。 Max 是一个柱状函数,适用于整个行集,在本例中为 table。 Greatest 从值(或变量)列表中选择 'maximum' 值。示例:
select greatest(1,4,3,5,7,0)
returns 7. 它也可以在作业中使用,如
something = greatest(...);
我认为您无法同时处理两列。这样的事情应该有效:
INSERT INTO strategy_registry (name, symbol, predictor_id, params, metric)
VALUES ({{ name }}, {{ symbol }}, {{ predictor_id }}, {{ params }}, {{ metric }})
ON CONFLICT (name, symbol, predictor_id)
DO UPDATE
SET params = CASE
WHEN metric < EXCLUDED.metric THEN EXCLUDED.params
ELSE params
END,
metric = GREATEST(metric, EXCLUDED.metric);
我认为其他答案应该可行,但是,我想说这可能不是实现此目标的最有效方法。相反,我会在更新中使用 WHERE
子句:
ON CONFLICT (name, symbol, predictor_id) DO UPDATE SET
metric = excluded.metric, params = excluded.params
WHERE excluded.metric > metric
即使值保持不变并导致 table 膨胀和额外的工作(另外,我认为它在语义上更清晰),先前的答案也可以进行更新。