2017-10-12 53 views
1

我是新來的mysql,並試圖研究它,但找不到任何解決方案。我有這樣一個表:MYSQL - 如何合併2行的相關數據到1

| SW_Pair1  | SW_Pair2  | Pair1_VLAN1| Pair1_VLAN2| Pair2_VLAN1| Pair2_VLAN2| Inter | Mgmt| OSPF| Env | Domain| 
    |-----------------|-----------------|------------|------------|------------|------------|-------|-----|-----|-----|-------| 
    | Switch1.abc.com | Switch2.abc.com | VLAN-111 | VLAN-333 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch2.abc.com | Switch1.abc.com | VLAN-222 | VLAN-444 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch3.abc.com | Switch4.abc.com | VLAN-121 | VLAN-123 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch4.abc.com | Switch3.abc.com | VLAN-515 | VLAN-717 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch5.abc.com | Switch6.abc.com | VLAN-919 | VLAN-101 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch6.abc.com | Switch5.abc.com | VLAN-105 | VLAN-108 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch7.abc.com | Switch8.abc.com | VLAN-110 | VLAN-115 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 
    | Switch8.abc.com | Switch7.abc.com | VLAN-199 | VLAN-200 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc | 

讓我們以前2行爲例。
SW_Pair1行1 == SW_Pair2在第2行== SW_Pair2行2 SW_Pair1爲1行

我把它們放在下一行,但他們可以在數據庫中的任何地方。現在我想將這兩個合併,以便第2行中的Pair1_VLAN1和Pair1_VLAN2中的數據進入第1行的Pair2_VLAN1和Pair2_VLAN2,然後第2行消失。所以,這裏是該表應如何合併後的樣子:

| SW_Pair1  | SW_Pair2  | Pair1_VLAN1| Pair1_VLAN2| Pair2_VLAN1| Pair2_VLAN2| Inter | Mgmt| OSPF| Env | Domain| 
|-----------------|-----------------|------------|------------|------------|------------|-------|-----|-----|-----|-------| 
| Switch1.abc.com | Switch2.abc.com | VLAN-111 | VLAN-333 | VLAN-222 | VLAN-444 | 47 | 24 | 0.1 | Dev | abc | 
| Switch3.abc.com | Switch4.abc.com | VLAN-121 | VLAN-123 | VLAN-515 | VLAN-717 | 47 | 24 | 0.1 | Dev | abc | 

等..

我使用Python 2.7將數據推到SQL。

編輯:

我想下面的查詢對DELETE添加額外的檢查,但它失敗:

UPDATE yourTable AS a 
DELETE FROM yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1 
WHERE Pair2_VLAN1 IS Unknown; 

或者更好的,它可以設置第二開關的Pair1_VLAN1和Pair1_VLAN2行的值後它將數據移動到開關1?也許會將vlan重寫爲「MERGED」之類的內容。然後,我可以安全地刪除Pair1_VLAN1和Pair1_VLAN2中「已合併」的任何內容。我知道它只會說當它的數據被成功移到另一行時。

EDIT2:

NVM ..想通了。請看下圖:

UPDATE yourTable AS a 
JOIN yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1 
SET a.Pair2_VLAN1 = b.Pair1_VLAN1, 
    a.Pair2_VLAN2 = b.Pair1_VLAN2, 
    b.Pair1_VLAN1 = "MERGED", 
    b.Pair1_VLAN2 = "MERGED 
WHERE a.SW_Pair1 < a.SW_Pair2; 
+0

你只是想顯示合併的數據,或者你真的想要在表中存儲合併的數據? –

+0

保存並刪除另一行。 – Damon

回答

2

首先更新在每一對與來自匹配行的數據的第一行:

UPDATE yourTable AS a 
JOIN yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1 
SET a.Pair2_VLAN1 = b.Pair1_VLAN1, 
    a.Pair2_VLAN2 = b.Pair1_VLAN2 
WHERE a.SW_Pair1 < a.SW_Pair2; 

WHERE子句確保只有一個在每對(一個與下名SW_Pair1)行被更新。

然後刪除未更新的行。它們在由第一個查詢更新的列中仍然有NULL

DELETE FROM yourTable 
WHERE Pair2_VLAN1 IS NULL; 

這假定每行都有匹配的行。如果你需要更安全的東西,你需要做一個連接來檢查是否有相反名稱的匹配行。

DELETE a FROM yourTable AS a 
JOIN yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1 
WHERE a.Pair2_VLAN1 IS NULL 
+0

這工作完美。無論如何要在DELETE上添加一些檢查,以便它不刪除沒有配對的交換機?我試圖制定一個查詢,但得到了SQL錯誤。請參閱我的編輯。 – Damon

+0

你不會在一個語句中結合'UPDATE'和'DELETE'。 – Barmar

+0

像魅力一樣工作,謝謝。最後一個問題,在將數據移動到開關1之後,是否可以設置第二個開關的Pair1_VLAN1和Pair1_VLAN2行的值?也許會將vlan重寫爲「MERGED」之類的內容。喜歡的東西:'SET a.'SEC_BB_A' = b.'PRI_BB_A', a.'SEC_BB_B' = b.'PRI_BB_B' b.'PRI_BB_A' =合併 b.'PRI_BB_B' = MERGED' – Damon

1

我敢肯定有一個更清潔的方式做到這一點,但是這是我想出了一個哈克的方式。

select 
a.sw_pair1, 
a.sw_pair2, 
a.pair1_vlan1, 
a.pair2_vlan1 as pair1_vlan2, 
b.pair1_vlan1 as pair2_vlan1, 
b.pair2_vlan1 as pair2_vlan2 

from TABLENAME a 
join TABLENAME b on a.sw_pair1 = b.sw_pair2 
where cast(substring_index(substring_index(a.sw_pair1, '.abc.com', 1), 'Switch', -1) as unsigned) % 2 > 0 

我使用模(%2),以確保我們僅在第一列中獲取奇數,因此其在列2的偶數我很好奇,看看別人可以爲我提供比我更清潔的解決方案。如果是這樣,那將有助於我進行一些我不時做的事情。

+1

如果您對另一種方法感到好奇,您可以查看我的答案。希望它會有所幫助。 –

+0

太棒了。感謝評論,所以我明白了。絕對有幫助。 –

+0

很高興爲您提供幫助。請爲了讓未來的訪客有所幫助而積極投票。謝謝。 –

1

此方法適用於我,似乎比當前的答案更簡單。這給了你想要的樣本數據輸出。

SELECT 
a.SW_Pair1, 
a.SW_Pair2, 
a.Pair1_VLAN1, 
a.Pair1_VLAN2, 
b.Pair1_VLAN1 as Pair2_VLAN1, 
b.Pair1_VLAN2 as Pair2_VLAN2 
FROM test as a , test as b 
WHERE a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2>b.SW_Pair2; 
1

如果您想要將合併的數據存儲到表中,那麼@ Barmar的解決方案將完美工作。

但如果你只是想顯示的數據,那麼下面的查詢將完成這項工作:

select least(t1.SW_Pair1,t1.SW_Pair2),greatest(t1.SW_Pair1,t1.SW_Pair2), 
     t2.Pair1_VLAN1,t2.Pair1_VLAN2, 
     t1.Pair1_VLAN1 as Pair2_VLAN1,t1.Pair1_VLAN2 as Pair2_VLAN2 
from tablet1 as t1 
inner join tablet2 as t2 
on t2.SW_Pair1 = t1.SW_Pair2 and t2.SW_Pair2=t1.SW_Pair1 
group by least(t1.SW_Pair11,t1.SW_Pair2),greatest(t1.SW_Pair1,t1.SW_Pair2); 

希望它能幫助!