【问题标题】:Why is there a duplicate primary key error in my postgresql insert statement when there is no duplicate? [closed]为什么我的postgresql插入语句中没有重复的主键出现重复的主键错误? [关闭]
【发布时间】:2020-12-07 02:07:33
【问题描述】:

注意:在阅读了一些 cmets 之后,我将查询更新为以下内容,这很有效。但也许有一个更简洁的解决方案。 这似乎可以解决问题...

insert into duplicates(contact_id_a, contact_id_b, ignore_duplicate, has_been_fetched, list_id, contact_a_name, contact_b_name) 
SELECT 32753, 42260, false, false, 567, (select data->>'firstname' as ca_firstname from contacts where contact_id = 32753),
(select data->>'firstname' as cb_firstname from contacts where contact_id = 42260) 
WHERE NOT EXISTS ( SELECT * FROM duplicates WHERE list_id = 567  
                  AND ((contact_id_a = 32753 and contact_id_b = 42260) OR (contact_id_a = 42260 and contact_id_b = 32753) ));

为什么我的 postgresql 查询在没有重复的情况下会引发这个重复的主键错误?

ERROR:  duplicate key value violates unique constraint "duplicates_pkey"
DETAIL:  Key (contact_id_a, contact_id_b, list_id)=(32753, 42260, 567) already exists.
SQL state: 23505

重复表是空的,所以我想新行是唯一的。

这里是查询。很清楚我在做什么,但简而言之,仅当重复表中没有包含指定的contact_ids和list_id的行时,才将新行插入到包含来自第二个表contacts的名称信息的重复表中.

insert into duplicates(contact_id_a, contact_id_b, ignore_duplicate, has_been_fetched, list_id, contact_a_name, contact_b_name) 
SELECT 32753, 42260, false, false, 567, ca.data->>'firstname', cb.data->>'firstname'
from contacts c 
left join contacts ca on ca.list_id=567 and ca.contact_id = 32753 
left join contacts cb on cb.list_id=567 and cb.contact_id = 42260 
WHERE NOT EXISTS ( SELECT * FROM duplicates WHERE list_id = 567  
                  AND ((contact_id_a = 32753 and contact_id_b = 42260) OR (contact_id_a = 42260 and contact_id_b = 32753) ));

这是我的主键约束...

【问题讨论】:

  • 请运行insert 的查询部分并注意这里返回了多少行。
  • 您的查询本身在 (contact_id_a, contact_id_b, list_id) 上返回重复项。
  • 太多了。谢谢你的提示。我现在看到我一直在从联系人表中提取每一行,而实际上我只想要来自包含指定联系人 ID 的行的数据。我按如下方式更新了选择查询,现在取回两行——两个指定的contact_id 各有一行。尽管如此,正如您所暗示的,select 语句必须只返回一行。我们所需要的只是让整个查询在重复表中插入一行,其中包含一些硬编码值和联系人表中的名称值。也许我根本不应该使用连接,而应该使用嵌套语句。
  • SELECT 32753, 42260, false, false, 567, ca.data->>'firstname', cb.data->>'firstname' from contacts c left join contacts ca on ca.list_id= 567 and ca.contact_id = 32753 left join contacts cb on cb.list_id=567 and cb.contact_id = 42260 where c.contact_id in (32753, 42260)
  • 我找到了一个最有效的解决方案。现在我该如何扩展它来管理 cb_firstname 呢?插入重复项(contact_id_a,contact_id_b,ignore_duplicate,has_been_fetched,list_id,contact_a_name) SELECT 32753, 42260, false, false, 567, ca_firstname from (select data->>'firstname' as ca_firstname from contacts where contact_id = 32753) as c WHERE NOT EXISTS (SELECT * FROM duplicates WHERE list_id = 567 AND ((contact_id_a = 32753 and contact_id_b = 42260) OR (contact_id_a = 42260 and contact_id_b = 32753)));

标签: postgresql duplicates primary-key


【解决方案1】:

在做任何事情之前尝试转储您的数据库,以便在出现任何问题时恢复到当前状态,然后尝试 REINDEX 您的数据库:

REINDEX DATABASE <YOUR-DBNAME>;

真空也可能是个好主意: vacuum(full, analyse, verbose);

【讨论】:

    【解决方案2】:

    select 返回多个具有相同组合键的行。

    您需要修复您的选择查询,以便每个组合键只返回一行。

    也许可以使用distinct

    insert into duplicates (...) 
    select distinct ... 
    

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2021-11-19
      • 1970-01-01
      相关资源
      最近更新 更多