Postgresql:将表的内容附加到另一个表

时间:2016-12-15 14:14:02

标签: database postgresql

我想在postgresql中合并两个具有相同列的表。实际上,我已经有一个表正在使用,并且想要从另一个服务器追加转储内容以合并表。两个表都有相同的列,包括主键一个...所以当我尝试加载转储时,我得到重复的主键错误。 我尝试将转储加载到一个单独的表中,并使用INSERT / SELECT将此新表的内容插入到第一个表中,但主键字段由于重复而生成错误,我无法在插入(或获得"非空约束"违规)。

使用正确的主键在第一个表(或其转储)的末尾附加第二个表(或其转储)的内容的语法(或解决方案)是什么?

简而言之,举个例子,我想:

#
# First table: 
#
CREATE TABLE t_table1 (
    f_fullcmd text,
    f_id integer NOT NULL,
    f_body text
);

INSERT INTO t_table1 VALUES ('command1', 1, 'This is my first command');
INSERT INTO t_table1 VALUES ('command2', 2, 'This is my second command');
INSERT INTO t_table1 VALUES ('command3', 3, 'This is my third command');

ALTER TABLE ONLY t_table1 ADD CONSTRAINT pk_1_t_table1 PRIMARY KEY (f_id);

#
# Second table to append to t_table1
#
CREATE TABLE t_table2 (
    f_fullcmd text,
    f_id integer NOT NULL,
    f_body text
);

INSERT INTO t_table2 VALUES ('run-1', 1, 'This is my first run');
INSERT INTO t_table2 VALUES ('run-2', 2, 'This is my second run');
INSERT INTO t_table2 VALUES ('run-3', 3, 'This is my third run');

ALTER TABLE ONLY t_table2 ADD CONSTRAINT pk_1_t_table2 PRIMARY KEY (f_id);

#
# Resulting table:
#
CREATE TABLE t_merge (
    f_fullcmd text,
    f_id integer NOT NULL,
    f_body text
);

INSERT INTO t_merge VALUES ('command1', 1, 'This is my first command');
INSERT INTO t_merge VALUES ('command2', 2, 'This is my second command');
INSERT INTO t_merge VALUES ('command3', 3, 'This is my third command');
INSERT INTO t_merge VALUES ('run-1', 4, 'This is my first run');
INSERT INTO t_merge VALUES ('run-2', 5, 'This is my second run');
INSERT INTO t_merge VALUES ('run-3', 6, 'This is my third run');

ALTER TABLE ONLY t_merge ADD CONSTRAINT pk_1_t_merge PRIMARY KEY (f_id);

输入是t_table1和t_table2的转储,并希望获得t_merge。

2 个答案:

答案 0 :(得分:1)

好的,经过一些试验和研究,看来这样做的顺序是:

--
-- First table: 
--
CREATE TABLE t_table1 (
    f_fullcmd text,
    f_id integer NOT NULL,
    f_body text
);

INSERT INTO t_table1 VALUES ('command1', 1, 'This is my first command');
INSERT INTO t_table1 VALUES ('command2', 2, 'This is my second command');
INSERT INTO t_table1 VALUES ('command3', 3, 'This is my third command');

ALTER TABLE ONLY t_table1 ADD CONSTRAINT pk_1_t_table1 PRIMARY KEY (f_id);

--
-- Second table to append to t_table1
--
CREATE TABLE t_table2 (
    f_fullcmd text,
    f_id integer NOT NULL,
    f_body text
);

INSERT INTO t_table2 VALUES ('run-1', 1, 'This is my first run');
INSERT INTO t_table2 VALUES ('run-2', 2, 'This is my second run');
INSERT INTO t_table2 VALUES ('run-3', 3, 'This is my third run');

ALTER TABLE ONLY t_table2 ADD CONSTRAINT pk_1_t_table2 PRIMARY KEY (f_id);

--
-- Create a temp table:
--
CREATE TABLE t_table3 (
    f_fullcmd text,
    f_id serial NOT NULL,
    f_body text
);

SELECT setval('t_table3_f_id_seq', (SELECT MAX(f_id)+1 FROM t_table1), false);

--
-- Merge table2 into table3
--
INSERT INTO t_table3 (f_fullcmd, f_body) SELECT f_fullcmd, f_body FROM t_table2;

--
-- Merge back into table1:
--
INSERT INTO t_table1 (f_fullcmd, f_id, f_body) SELECT f_fullcmd, f_id, f_body FROM t_table3;

创建t_table3时,将主键更改为序列,然后将其起始值设置为第一个表主键+1的最大值,将t_table2的内容插入t_table3(重新生成主键为一个序列),最后将t_table3的内容导回到t_table1。

答案 1 :(得分:0)

如果两个表都是自动数字,而不是创建时态表,那么这样做更简单:

INSERT INTO t_table1 (f_fullcmd, f_id, f_body) 
SELECT f_fullcmd, 
       f_id + x.t1_max, 
       f_body 
FROM t_table2
CROSS JOIN (SELECT MAX(f_id) t1_max FROM t_table1) x ;