2

我有一个contacts表,该表具有自动递增的主键id和列上的自引用一对一关系partner_id

我正在从各种来源的 CSV 中导入许多联系人,其中一些联系人的呈现方式非常糟糕,因此我必须运用一些聪明才智来确定谁是谁的合作伙伴,如果他们有的话。

我已经到了导入后的阶段,我在联系人表中有行,并且我确定为合作伙伴的任何对都在列中共享该对的唯一值import_group

我现在坚持编写查询来执行以下操作:

如果两行在 中共享相同的值import_group,则将partner_id两行中的第一行设置为两行id中的第二行,但不要partner_id将第二行设置为第一行id。由于引用此数据库的应用程序的设计,此结构是必需的。

这将在包含最多约 4,000,000 行的表上运行,在系统管理员运行的手动导入期间每月少于一次,因此效率不是此查询的特定目标。

我该怎么办?

4

2 回答 2

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 fiddle,所以这是我测试它的方法:

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)
于 2013-07-10T13:26:39.823 回答
0

您可以通过自加入来识别所有合作伙伴。然后,您只想设置具有 "lower" 的那个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;

注意:这假设所有伙伴关系都是二元的。如果您有多方合作伙伴关系,则需要更多关于数据应该是什么样子的信息。

于 2013-07-10T13:28:46.893 回答