【发布时间】: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