Postgres 9.4 -- 在 table 中插入行时如何忽略重复键
Postgres 9.4 -- How do I ignore duplicate key when inserting rows into a table
我有一个这样的story_id
table。
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 = 12
和 story_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
);
你很接近。您只需要将 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
,在 documentation 中对 insert
进行了解释。
从版本 9.4 升级到 9.5 不要发出 子请求 。它会导致 性能下降 。 从 Postgres 9.5 开始 你可以简单地使用:
INSERT INTO my_table (id, name) VALUES (1, 'Me')
ON CONFLICT DO NOTHING;
我有一个这样的story_id
table。
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 = 12
和 story_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
);
你很接近。您只需要将 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
,在 documentation 中对 insert
进行了解释。
从版本 9.4 升级到 9.5 不要发出 子请求 。它会导致 性能下降 。 从 Postgres 9.5 开始 你可以简单地使用:
INSERT INTO my_table (id, name) VALUES (1, 'Me')
ON CONFLICT DO NOTHING;