postgresql从select中插入

时间:2016-07-20 19:01:03

标签: sql database postgresql

我有两个表table1和test_table1,它们具有相同的模式。

两个表都有行/数据,pk id从1开始。

我想这样做:

insert into test_table1 select * from table1;

但由于test_table1中存在table1的pk值而失败。

方法是指定列并保留pk列,但由于某些原因,它们不起作用:

e.g。 注 - 下面的查询中没有pk列

insert into test_table1 (col1, col2,..., coln) select col1,col2,...,coln from table1;

返回

  

错误:重复键值违反了唯一约束“test_table1_pkey”   DETAIL:Key(id)=(1)已经存在。

我知道这在MySql中有效,这是仅仅归功于Postgresql?不管怎么说呢?

编辑:

两个表都有主键和序列集。

由于不清楚 - 表没有相同的数据。 我只想将table1中的行添加到test_table1。

对于要求我从查询中排除主键的答案 - 我按照之前的说法做了。

4 个答案:

答案 0 :(得分:2)

只需从查询列中删除pk列

即可
insert into test_table1 (col2,..., coln) select col2,...,coln from table1;

如果它仍然失败,你可能还没有对pk列进行排序。  在现有的pk列上创建序列

create sequence test_table1_seq;
ALTER TABLE test_table1 
    ALTER COLUMN col1 SET DEFAULT nextval('test_table1_seq'::regclass);

并将序列值更新为当前

SELECT setval('test_table1_seq', (SELECT MAX(col1) FROM test_table1));

答案 1 :(得分:0)

您宁愿做UPDATE JOIN之类的

UPDATE test_table1 AS v 
SET col1 = s.col1,
col2 = s.col2,
col3 = s.col3,
.....
colN = s.colN
FROM table1 AS s
WHERE v.id = s.id; 

答案 2 :(得分:0)

你想要做的是一个upsert。

with upsert as (
    update test_table1 tt
    set col1 = t.col1,
        col2 = t.col2,
        col3 = t.col3
    from table1 t
    where t.id = tt.id 
    returning *
)
insert into test_table1(id, col1, col2, col3)
select id, col1,col2,col3
from table1
where not exists (select * from upsert)

答案 3 :(得分:0)

This post帮我解决了问题,不知道出了什么问题:

  

如何修复PostgreSQL错误"重复密钥违反了唯一约束"

     

如果在尝试将数据插入PostgreSQL数据库时收到此消息:

     
    

错误:重复键违反了唯一约束

  
     

这可能意味着您正在使用的表中的主键序列以某种方式变得不同步,这可能是因为大量导入过程(或者沿着这些行)。在设计"中将其称为“错误”,但似乎必须在从转储文件恢复后手动重置主键索引。无论如何,要查看您的值是否不同步,请运行以下两个命令:

SELECT MAX(the_primary_key) FROM the_table;
SELECT nextval('the_primary_key_sequence');
     

如果第一个值高于第二个值,则序列不同步。备份PG数据库(以防万一),然后运行thisL

SELECT setval('the_primary_key_sequence', (SELECT MAX(the_primary_key) FROM the_table)+1);
     

这会将序列设置为下一个可用值,该值高于序列中任何现有的主键。