2016-12-15 45 views
-1

我想合并两个表PostgreSQL中相同的列。实际上,我已经有一个表正在使用,并希望追加来自另一台服务器的转储内容以合并这些表。这两个表都有相同的列,包括主键...所以当我尝试加载转储时,我得到重复的主键错误。 我试图转储加载到一个单独的表,并插入这个新表的内容到第一个与INSERT/SELECT,但主键字段生成,因为重复的错误,我不能在省略它插入(或获得“非空约束”违规)。PostgreSQL的:一个表的内容追加到另一个表

会是什么语法(或溶液)到所述第二表中的第一个的端部的内容(或它的转储)追加,以正确的主键?

总之,有一个例子,我想:

# 
# 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。

+0

什么是“正确”的主键?通常如何生成第一个表的键? –

+0

你有一个自动数字字段是主键吗?如果你的表A有'pkField_id = 1',表B也有'pkField_id = 1',你期望得到什么结果? –

+0

你可能会问错了问题[**什么是XY问题?**](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) ,因为如果两个表有相同的ID,你会违反PK。所以你需要创建一个不同的领域成为PK。或者决定什么是可行的解决方法。 –

回答

0

OK,所以一些试验和研究后,似乎序列来做到这一点:

-- 
-- 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中。

0

如果两个表是autonumeric不已,而不是创建一个态表是简单的做到这一点:

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 ; 
相关问题