Postgres 9.4-在表中插入行时如何忽略重复键

时间:2018-12-07 01:59:12

标签: sql postgresql postgresql-9.4

我有一个story_id表,像这样。

    Column    |  Type   |                             Modifiers
--------------+---------+-------------------------------------------------------------------
 id           | integer | not null default nextval('story_sites_id_seq'::regclass)
 story_id     | integer | not null
 site_id      | integer | not null

我想用site_id = 12story_id添加已经具有site_id = 70的新行,这是我的查询,它运行良好:

INSERT INTO story_sites (story_id, site_id)
SELECT story_id, 12
FROM story_sites
WHERE site_id = 70;

但是,如果有已经有site_id = 12的行,我将收到重复的键错误。

所以我想排除那些重复的行,这是我的新查询,但是它不能正常工作,在我认为应该插入时不插入任何内容。而且看来我在Postgres 9.4中不能使用ON CONFLICT DO NOTHING。我该怎么办?

INSERT INTO story_sites (story_id, site_id)
SELECT story_id, 12
FROM story_sites
WHERE site_id = 70
AND NOT EXISTS
(
    SELECT id
    FROM story_sites
    WHERE site_id = 12
);

2 个答案:

答案 0 :(得分:2)

您很近。您只需要考虑story_id

INSERT INTO story_sites (story_id, site_id)
    SELECT ss.story_id, 12
    FROM story_sites ss
    WHERE ss.site_id = 70 AND
          NOT EXISTS (SELECT id
                      FROM story_sites ss2
                      WHERE ss2.site_id = 12 AND ss2.sotry_id = ss.story_id
                     );

总而言之,如果同时发生多个插入,则此查询仍有可能出现问题。您真正应该使用的是on conflict do nothing,在insert的{​​{3}}中对此进行了解释。

答案 1 :(得分:-1)

从9.4版本升级到9.5请勿进行 subrequests 。这可能会导致性能下降。 自Postgres 9.5起,您可以简单地使用:

INSERT INTO my_table (id, name) VALUES (1, 'Me') 
ON CONFLICT DO NOTHING;