2017-10-16 131 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