2017-10-16 33 views
6

在mysql数据库中,我有一个业务单元表,它维护客户业务单元的层次结构。每个业务部门都可以有父母和/或孩子。mysql - 删除父子关系后保留唯一记录

products_client_1.business_units

id parent_id 
1 
2 1 
3 1 
4 1 
8 1 
14 3 
17 2 
31 1 
35 4 
36 1 
37 4 
38 2 
39 31 
40 8 
41 3 
42 31 
43 
44 43 

目前,我有一个客户ID表,保存在客户在业务单元层面

contacts_client_1.buid_customer_id

global_id customer_id bu_id 
ABC1000033 1812130  2 
ABC1000033 1812130  54 
ABC1000034 4049809  2 
ABC1000035 5630631  2 
ABC1000082 5707052  2 
ABC1000082 1111116  54 
ABC1000091 5813085  2 
ABC1000091 5813085  54 
ABC1000093 5208477  2 
ABC1000115 5045891  2 
ABC1000115 5045891  54 
ABC1000117 6114245  2 
ABC1000117 6114247  54 
ABC1000117 6114247  1 
ABC1000111 1234567  38 
ABC1000100 9023456  43 
ABC1000100 9023457  44 

展望未来,我不想保持习惯mer个人业务部门级别。对于给定的globalId,它应该是唯一的。为此,我想根据以下条件迁移现有的客户ID数据。

如果globalId对于唯一的单个BU具有customerId,请将其原样迁移,而不使用bu_id。

如果globalId具有2个BU的customerId(它们可以是任何级别的父子),请保留父可用BU的customerId。

所需的表contacts_client_1.customer_id

global_id customer_id 
ABC1000033 1812130 
ABC1000034 4049809 
ABC1000035 5630631 
ABC1000082 5707052 
ABC1000091 5813085 
ABC1000093 5208477 
ABC1000100 9023456 
ABC1000111 1234567 
ABC1000115 5045891 
ABC1000117 6114247 

PS: globalId不是不同的父MOST总线之间重叠。

business_unit表位于products_client_1架构下,而buid_customer_id表位于contacts_client_1架构下。

相同的代码应该可以执行不同的客户端。

这是一次性迁移。

在编写查询时需要帮助。

+0

你想删除'buid_customer_id'表行? –

+1

什么决定“最可用”?在您的示例数据中,请标记哪些需要删除。 –

+0

我想删除BU_ID列。截至目前,主键是Global_id + BU_ID。 customer_id处于BU级别。现在我想删除这个约束并将其存储在客户端。现有数据应该迁移到只有Global_id作为主键的新表中。 –

回答

0

我不知道你会用你的数据到底该怎么做,但下面应该有所帮助:

只显示其具有在buid_customer_id表中没有父为同一global_id行:

select child.* 
from contacts_client_1.buid_customer_id child 
left join products_client_1.business_units bu 
    on bu.id = child.bu_id 
left join contacts_client_1.buid_customer_id parent 
    on parent.global_id = child.global_id 
    and parent.bu_id  = bu.parent_id 
where parent.global_id is null 

实例:

  • (ABC1000100 9023456 43) - 的bu_id(43)具有在buid_customer_id没有父,所以不会有垫第一个左连接,第二个也没有匹配。由于左连接表中的所有列都将为NULL,因此​​为TRUE,并且该行将被选中。
  • (ABC1000100 9023457 44) - bu_id(44)有一个parent_id(43),所以第一个JOIN将找到一个匹配。第二个JOIN也会找到一个匹配项,因为在buid_customer_id表中存在具有父BU和global_id的行。因此parent.global_id不为NULL,并且该行不会被选中。
  • (ABC1000033 1812130 2) - bu_id(2)有一个parent_id(1)。第一个JOIN会找到一个匹配项。但是表中的bu_id = 1global_id = ABC1000033表中没有一行,所以第二个JOIN没有匹配。因此parent.global_id将为NULL,并且该行将被选中。

现在你可以使用这个语句复制(迁移)的数据到新表

insert into new_table 
    select child.* 
    [..] 

你也可以走另一条路。如果使用INNER JOIN替换LEFT JOIN并删除WHERE子句,则会得到相反的结果(第一个查询未返回的所有行)。您可以使用它从表中删除所有这些行。

删除其中有一个父行对同一global_id所有行:

delete child 
from contacts_client_1.buid_customer_id child 
join products_client_1.business_units bu 
    on bu.id = child.bu_id 
join contacts_client_1.buid_customer_id parent 
    on parent.global_id = child.global_id 
    and parent.bu_id  = bu.parent_id 

现在表buid_customer_id将包含由第一个查询选定的同一行。如果这个数据需要在另一个表中 - 只需重命名它。然后,你可以复制global_idcustomer_id

insert into customer_id (global_id, customer_id) 
    select global_id, customer_id 
    from new_table