如果某些数据丢失,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 会自动插入以前的值的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL数据库导入大量数据时如何优化

PostgreSQL数据库导入大量数据时如何优化

PostgreSQL数据库导入大量数据时如何优化

追踪丢失键盘插入符号的情况

防止在 postgres 上的异步插入重复

postgres 将字符串插入数字列 - 不会发生自动类型转换