gpt4 book ai didi

postgresql - 仅当新数据与最新插入不同时才将新数据插入表中

转载 作者:行者123 更新时间:2023-11-29 14:30:48 24 4
gpt4 key购买 nike

我想将股票价格添加到表格中 - 但前提是买入或卖出与上一条记录相比发生变化。因此 UNIQUE 并没有真正起作用,因为它不允许在表中多次出现相同的价格组合。我可以想办法解决 postgres 之外的问题(在实际插入行之前),但我想知道是否有办法设置价格表为我处理这个问题。

CREATE TABLE stock(
id SMALLSERIAL PRIMARY KEY,
name VARCHAR(3) UNIQUE NOT NULL
);

CREATE TABLE prices(
id SMALLSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT current_timestamp,
stock_id INTEGER NOT NULL,
buy NUMERIC(15, 6) NOT NULL,
sell NUMERIC(15, 6) NOT NULL,
FOREIGN KEY (stock_id) REFERENCES stock(id),
UNIQUE(stock_id, buy, sell)
);


INSERT INTO stock(name) VALUES('abc');
INSERT INTO prices (stock_id, buy, sell) VALUES (1, 1.5, 1.4)
ON CONFLICT (stock_id, buy, sell) DO NOTHING;
INSERT INTO prices (stock_id, buy, sell) VALUES (1, 1.5, 1.4)
ON CONFLICT (stock_id, buy, sell) DO NOTHING; -- this record should not be added to the table
INSERT INTO prices (stock_id, buy, sell) VALUES (1, 1.6, 1.5)
ON CONFLICT (stock_id, buy, sell) DO NOTHING;
INSERT INTO prices (stock_id, buy, sell) VALUES (1, 1.5, 1.4)
ON CONFLICT (stock_id, buy, sell) DO NOTHING; -- this one should be added to the table

sqlfiddle

所以在我的示例中,我希望表格中有 3 行而不是 2 行 - 只有第 2 行插入价格应该被阻止,而不是第 4 行。

最佳答案

如您所写,唯一约束不是解决问题的合适方法。在这种情况下,触发器是一种自然的方法,例如:

create or replace function before_insert_on_prices()
returns trigger language plpgsql as $$
declare
last_rec record;
begin
select buy, sell
from prices
where stock_id = new.stock_id
order by created_at desc
limit 1
into last_rec;

if found and last_rec = (new.buy, new.sell) then
return null;
end if;
return new;
end $$;

create trigger before_insert_on_prices
before insert on prices
for each row execute procedure before_insert_on_prices();

请注意,只有在单独的事务中插入新行时触发器才能正常工作,因为在单个事务中插入的多行在 created_at 中具有相同的时间戳。但是,我认为这种行为是合乎逻辑且可以接受的。

Working example in rextester.

关于postgresql - 仅当新数据与最新插入不同时才将新数据插入表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52174147/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com