【问题标题】:To ignore duplicate keys during 'copy from' in postgresql在 postgresql 中的“复制自”期间忽略重复的键
【发布时间】:2012-12-06 12:09:36
【问题描述】:

我必须将大量数据从文件转储到表 PostgreSQL。我知道它不支持 MySql 中的“忽略”“替换”等。网络上几乎所有与此相关的帖子都提出了相同的建议,例如将数据转储到临时表中,然后执行“插入...选择...在不存在的地方...”。

这在文件数据本身包含重复主键的一种情况下无济于事。 任何人都知道如何在 PostgreSQL 中处理这个问题?

附:如果有帮助,我正在从 java 程序中执行此操作

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    使用与您描述的方法相同的方法,但 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)
    

    详细信息:CREATE TABLE ASCOPYDISTINCT ON

    【讨论】:

    • 当我尝试复制命令时出现错误:关系“tmp_table”不存在
    • @Nate 您在执行COPY 命令之前是否创建了tmp_table
    • @Nate 当使用 psql 或其他具有自动提交功能的客户端时,只需从第一条语句中省略 ON COMMIT DROP,并在最后执行 DROP TABLE tmp_table;
    • 调整:在更现代的 PSQL 上使用 upsert,例如ON CONFLICT DO NOTHING 用于 INSERT 语句。
    • 用事务 (begin; ...; commit;) 包装答案代码,以便on commit drop 将在事务结束时删除临时表。否则表格将立即下降,就在copyinsert into 有机会运行之前。因此“tmp_table 不存在”。
    【解决方案2】:

    PostgreSQL 9.5 现在有upsert functionality。您可以按照 Igor 的说明进行操作,但最后的 INSERT 包含子句 ON CONFLICT DO NOTHING。

    INSERT INTO main_table
    SELECT *
    FROM tmp_table
    ON CONFLICT DO NOTHING
    

    【讨论】:

    • 谢谢你,你拯救了我的一天。
    【解决方案3】:

    Igor 的回答对我帮助很大,但我也遇到了 Nate 在他的评论中提到的问题。然后我遇到了一个问题——也许除了这里的问题之外——新数据不仅在内部包含重复,而且还与现有数据重复。对我有用的是以下内容。

    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 然后丢弃所有其他行。

    【讨论】:

      【解决方案4】:

      插入到按键分组的临时表中,以便消除重复项

      如果不存在则插入

      【讨论】:

        猜你喜欢
        • 2011-01-22
        • 2015-05-25
        • 1970-01-01
        • 2018-06-01
        • 2015-10-15
        • 1970-01-01
        • 1970-01-01
        • 2016-04-16
        • 1970-01-01
        相关资源
        最近更新 更多