我有一个contacts
表,其中包含自动递增的主键id
以及partner_id
列上的自引用一对一关系。
我从各种来源的CSV中导入了很多联系人,其中一些联系人的表现很差,所以我不得不应用一些智能来找出谁是合作伙伴,如果他们有合作伙伴的话。
我已经进入了导入后的阶段,我在联系人表格中有行,而我确定为合作伙伴的任何对都在import_group
列中共享该对唯一的值。
我现在不得不写一个查询来执行以下操作:
如果两行在import_group
中共享相同的值,请将两行中第一行的partner_id
设置为两行中第二行的id
,但不要设置第一行的partner_id
到第一行的id
。由于引用此数据库的应用程序的设计,此结构是必需的。
这将在一个包含最多约4,000,000行的表上运行,在系统管理员运行的手动导入期间每月少于一次,因此效率不是此查询的特定目标。
我该如何解决这个问题?
答案 0 :(得分:2)
使用自联接,如果按id排序,则可以使用WHERE子句确保只获得每对中的一个。例如,
UPDATE contacts as c1
JOIN contacts as c2
ON c2.import_group = c1.import_group
SET c1.partner_id = c2.id
WHERE c1.id < c2.id;
我无法访问sql小提琴,所以这是我测试它的方式:
create table contacts (id int, import_group int, partner_id int);
insert into contacts values (1, NULL, NULL), (2, 100, NULL), (3, 100, NULL), (4, NULL, NULL), (5, 101, NULL), (6, NULL, NULL), (7, 101, NULL);
select * from contacts;
+------+--------------+---------+
| id | import_group | partner |
+------+--------------+---------+
| 1 | NULL | NULL |
| 2 | 100 | 3 |
| 3 | 100 | NULL |
| 4 | NULL | NULL |
| 5 | 101 | 7 |
| 6 | NULL | NULL |
| 7 | 101 | NULL |
+------+--------------+---------+
7 rows in set (0.00 sec)
答案 1 :(得分:0)
您可以通过自我加入识别所有合作伙伴。然后,您只想设置具有“较低”contact.id
的那个。
以下更新会在contact
上自我加入以查找合作伙伴。然后它有一个不等式,所以它保留了set
的第一行:
update contacts c join
contacts cpart
on c.import_group = cpart.import_group and
c.id < cpart.id
set c.partner_id = cpart.id;
注意:这假设所有合作伙伴都是二元的。如果您有多方合作关系,那么需要更多关于数据应该是什么样的信息。