我有一张联系人表。该表包含一个mobile\u phone列和一个home\u phone列。我想获取所有成对的重复联系人,其中一对是两个联系人共享一个电话号码。
请注意,如果联系人a的移动电话与联系人b的家庭电话匹配,则这也是一个副本。下面是三个应该匹配的联系人的示例。
contact_id|mobile_phone|home_phone|other columns such as email.......|...
-------------------------------------------------------------------------
111 |9748777777 |1112312312|..................................|...
112 |1112312312 |null |..................................|...
113 |9748777777 |0001112222|..................................|...
具体来说,我想返回一个表,其中每行包含两个匹配联系人的联系人ID。例如,
||contact_id_a|contact_id_b||
||-------------------------||
|| 145155 | 145999 ||
|| 145158 | 145141 ||
借助@erwin here enter link description here,我可以编写一个接近我要实现的目标的查询,返回列表中所有联系人的联系人ID列表,这些联系人与列表中的其他联系人共享一个电话号码。
SELECT c.contact_id
FROM contacts c
WHERE EXISTS (
SELECT FROM contacts x
WHERE (x.data->>'mobile_phone' is not null and x.data->>'mobile_phone' IN (c.data->>'mobile_phone', c.data->>'home_phone'))
OR (x.data->>'home_phone' is not null and x.data->>'home_phone' IN (c.data->>'mobile_phone', c.data->>'home_phone'))
AND x.contact_id <> c.contact_id -- except self
);
输出只包含如下联系人ID。。。
||contact_id||
--------------
|| 2341514 ||
|| 345141 ||
我想将匹配联系人的联系人ID放在一行中,如上所示。
4条答案
按热度按时间vltsax251#
一个简单的查询是使用array overlap操作符
&&
:条件
c1.contact_id < c2.contact_id
排除自联接和切换的重复项。但是,如果许多联系人以某种方式共享相同的号码,这种表示很快就会失控。
旁白:条件
[INNER] JOIN
以及WHERE
条件完全相同,但不超过join_collapse_limit
涉及连接。请参见:有条件的大表联接的计数很慢
n3schb8v2#
简化的模式更短:
它的意思是:联系人1和3共享电话1,联系人1、2和4共享电话2,电话3仅与联系人3相关,联系人4仅具有电话5,联系人2具有空电话。您可以根据自己的具体需求来筛选结果。
你也可以使用
array_agg(distinct x)
排除重复项(如有)。epfja78i3#
一个简单的解决方案是自连接:
这将为每对“重复”联系人提供一行,第一列中的联系人id最小。
5jdjgkvh4#
这个怎么样?