【问题标题】:Inserting new records into table with row number as id with PostgreSQL使用 PostgreSQL 将新记录插入以行号为 id 的表中
【发布时间】:2015-03-25 13:36:02
【问题描述】:

我有一个数据库表,我们称之为Foo。 Foo 有一个id 列(很长),还有一些数据列,我们称它们为Bar1Bar2

在出现id 列之前,有一个脚本可以正常工作,它可以像这样简单地将新内容添加到表中:

INSERT INTO Foo
SELECT OldBar1, SUM(OldBar2)
FROM OldFoo
GROUP BY OldBar1

现在,在添加了id 之后,如果我有一个新的Foo 表最初是空的,那么我可以这样做:

INSERT INTO Foo
SELECT row_number() OVER() as id, OldBar1, SUM(OldBar2)
FROM OldFoo
GROUP BY OldBar1;

并且Foo 表中的数据将具有它们的ids 相同的行号。

但是,当Foo 表中存在现有数据并且我执行上一个查询时,我得到一个异常,指出“Key (id)=(1) 已经存在”。

显然,我不希望 row_number 查看源 OldFoo 表,而是查看新的 Foo 表。

在 Java 中绘制一个并行示例,使用 HashMap<Integer, Foo> 作为存储库:

map.put(map.size() + 1, fooObject);

有没有办法实现这一点,生成与目标表中的行号相同的 ID?

【问题讨论】:

标签: java sql postgresql insert primary-key


【解决方案1】:

我强烈建议找到一种使用serial 的方法。但是,假设表上没有发生其他 insert 操作,则以下内容应该适合您:

INSERT INTO Foo
    SELECT (f.maxId + row_number() OVER() )as id, OldBar1, SUM(OldBar2)
    FROM OldFoo CROSS JOIN
         (SELECT MAX(id) as MAX(ID) FROM Foo) f
    GROUP BY OldBar1, f.maxId;

一条建议:使用INSERT 时,请始终包含列名。所以你的查询应该是INSERT INTO Foo(Id, OldBar)。这使得代码更易于维护和理解。

【讨论】:

  • 当然,我只是使用Fooa 和Bars 来隐藏真实的表名和列名:D 你能告诉我这种插入方式的性能吗?跨度>
  • 一个问题:使用这种方法会出现以下错误:ERROR: column "f.maxid" must appear in the GROUP BY clause or be used in an aggregate function
  • 看来@GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; 转换为SERIAL,这让我的生活变得更轻松:D 非常感谢,已接受回答:D
猜你喜欢
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
相关资源
最近更新 更多