【问题标题】:INSERT into a table from SELECT only if value doesn't exist仅当值不存在时才从 SELECT 插入表
【发布时间】:2015-12-19 09:40:22
【问题描述】:

我想将 table1.id 插入到 table2.t1col 中,前提是 table1.id 尚不存在于 table2.t1col 中。

我想我必须使用:

insert into table2 name (t1col) value (select id from table1)

但我只想在id 已在table2 中不存在的情况下添加。

【问题讨论】:

    标签: sql postgresql sql-insert upsert


    【解决方案1】:

    唯一/索引约束保证值的唯一性。所以,推荐。

    不幸的是,违反约束会导致整个insert 失败。所以,你可以这样做:

    insert into table2(t1col) 
        select id
        from table1 t1
        where not exists (select 1 from table2 t2 where t2.t1col = t1.id);
    

    您还应该有一个唯一的索引/约束以防止将来出现问题。

    【讨论】:

      【解决方案2】:

      如果你对table2.t1col 有一个UNIQUEPRIMARY KEY 约束,就像你最可能应该的那样,Postgres 9.5 有一个更优雅的解决方案(目前是测试版,将正式发布现在很快)。使用新的 UPSERT 实现 INSERT ... ON CONFLICT DO NOTINGQuoting the manual:

      可选的ON CONFLICT 子句指定了一个替代操作 引发唯一违反或排除约束违反错误。 对于建议插入的每一行,插入 继续进行,或者,如果仲裁约束或索引由 conflict_target 被违反,采取替代的冲突动作。 ON CONFLICT DO NOTHING 只是避免插入一行作为其替代操作。

      我的大胆强调。

      所以你可以简单地:

      INSERT INTO table2(t1col)
      SELECT id FROM table1
      ON CONFLICT DO NOTHING;
      

      如果table1.id 没有被定义为唯一的,使它是唯一的:

      INSERT INTO table2(t1col)
      SELECT DISTINCT id FROM table1
      ON CONFLICT DO NOTHING;
      

      对于 Postgres 9.4,您可以在此处找到技术概述:

      【讨论】:

        【解决方案3】:

        您可以使用唯一索引来防止重复行。

        但是如果你想插入行过滤它不插入重复的行,你可以这样做。

        INSERT INTO table2 (idcol)
        SELECT id FROM table1
        EXCEPT
        SELECT idcol FROM table2;
        

        【讨论】:

          【解决方案4】:

          在该列上创建一个唯一索引并完成它。无需检查。

          CREATE UNIQUE INDEX name ON table (column [, ...]);
          

          http://www.postgresql.org/docs/9.4/static/indexes-unique.html

          【讨论】:

            【解决方案5】:

            使用这个查询

            INSERT INTO table2 name (t1col) value 
            (
                SELECT t1.id FROM table1 t1, table2 t2
                WHERE t1.id <> t2.id
            )
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-11-22
              • 2017-04-21
              • 2016-05-07
              • 2013-04-28
              • 1970-01-01
              相关资源
              最近更新 更多