如果某些数据丢失,Postgres 会自动插入以前的值
Posted
技术标签:
【中文标题】如果某些数据丢失,Postgres 会自动插入以前的值【英文标题】:Postgres auto insert with previous values if some data misses 【发布时间】:2020-11-27 12:35:34 【问题描述】:我有日期范围的数据,有些日期几天都不会出现,在错过的窗口期间我只想插入以前的数据。
有没有办法在自己插入数据时处理这个问题
例如
create table foo (ID VARCHAR(10), foo_count int, actual_date date);
insert into foo ( values('234534', 100, '2017-01-01'),('234534', 200, '2017-01-02'));
insert into foo ( values('234534', 300, '2017-01-03') );
insert into foo ( values('234534', 300, '2017-01-08') );
在最后一次插入之后,我可以确保生成以前的数据
所以它应该看起来像这样
ID | foo_count | actual_date
-----------+-----------------+------------
234534 | 100 | 2017-01-01
234534 | 200 | 2017-02-01
234534 | 300 | 2017-03-01
234534 | 300 | 2017-04-01
234534 | 300 | 2017-05-01
234534 | 300 | 2017-06-01
234534 | 180 | 2017-07-01
我正在使用 JPA 插入它,目前我查询表并查看表中的当前日期并填充缺失的数据
【问题讨论】:
【参考方案1】:我会考虑一个更好的INSERT
声明。从SELECT
语句插入会使事情变得更容易。 SELECT
语句可用于生成请求的日期系列。
INSERT INTO foo
SELECT
--<advanced query>
但是,我想这不是简单的可能,因为您没有直接使用 JDBC 或想要使用本机查询来插入数据。
在这种情况下,您可以在数据库中安装一个触发器,它可以发挥神奇的作用:
demo:db<>fiddle
触发功能:
CREATE FUNCTION insert_missing()
RETURNS TRIGGER AS
$$
DECLARE
max_record record;
BEGIN
SELECT -- 1
id,
foo_count,
actual_date
FROM
foo
ORDER BY actual_date DESC
LIMIT 1
INTO max_record;
IF (NEW.actual_date - 1 > max_record.actual_date) THEN -- 2
INSERT INTO foo
SELECT
max_record.id,
max_record.foo_count,
generate_series(max_record.actual_date + 1, NEW.actual_date - 1, interval '1 day'); -- 3
END IF;
RETURN NEW;
END;
$$ language 'plpgsql';
-
查询当前最大日期的记录。
如果最大日期比新日期早一天...
... 插入日期系列(从当前最大日期之后的一天到新日期之前的日期)。这可以使用
generate_series()
生成。
然后创建ON BEFORE INSERT
触发器:
CREATE TRIGGER insert_missing
BEFORE INSERT
ON foo
FOR EACH ROW
EXECUTE PROCEDURE insert_missing();
【讨论】:
以上是关于如果某些数据丢失,Postgres 会自动插入以前的值的主要内容,如果未能解决你的问题,请参考以下文章