我必须将大量数据从文件转储到表PostgreSQL。我知道它不支持'忽略''替换'等在MySql中完成。几乎所有关于这一点的帖子都提出了相同的建议,例如将数据转储到临时表,然后执行“插入...选择......不存在......”。
在一种情况下,这将无济于事,其中文件数据本身包含重复的主键。 任何机构都知道如何在PostgreSQL中处理这个问题?
P.S。我正在从java程序中执行此操作,如果它有帮助
答案 0 :(得分:55)
使用与您描述的方法相同的方法,但在加载到主表之前,DELETE
(或组,或修改...)在临时表中复制PK
。
类似的东西:
CREATE TEMP TABLE tmp_table
ON COMMIT DROP
AS
SELECT *
FROM main_table
WITH NO DATA;
COPY tmp_table FROM 'full/file/name/here';
INSERT INTO main_table
SELECT DISTINCT ON (PK_field) *
FROM tmp_table
ORDER BY (some_fields)
答案 1 :(得分:28)
PostgreSQL 9.5现在有upsert functionality。您可以按照Igor的说明进行操作,但最终的INSERT包含“冲突没有”的条款。
INSERT INTO main_table
SELECT *
FROM tmp_table
ON CONFLICT DO NOTHING
答案 2 :(得分:11)
CREATE TEMP TABLE tmp_table AS SELECT * FROM newsletter_subscribers;
COPY tmp_table (name, email) FROM stdin DELIMITER ' ' CSV;
SELECT count(*) FROM tmp_table; -- Just to be sure
TRUNCATE newsletter_subscribers;
INSERT INTO newsletter_subscribers
SELECT DISTINCT ON (email) * FROM tmp_table
ORDER BY email, subscription_status;
SELECT count(*) FROM newsletter_subscribers; -- Paranoid again
内部和外部重复项在tmp_table
中变得相同,然后DISTINCT ON (email)
部分将其删除。 ORDER BY
确保所需的行在结果集中排在第一位,DISTINCT
然后丢弃所有其他行。
答案 3 :(得分:0)
插入按键分组的临时表,以便删除重复项
然后插入(如果不存在)