2010-05-13 86 views
1

我有一個表是這樣的:MySQL ::消除表中的冗餘元素?

+-------+---------+------+-----+---------+-------+ 
| Field | Type | Null | Key | Default | Extra | 
+-------+---------+------+-----+---------+-------+ 
| v1 | int(11) | YES | MUL | NULL |  | 
| v2 | int(11) | YES | MUL | NULL |  | 
+-------+---------+------+-----+---------+-------+ 

有重複的在這個表中的巨大數額。例如,以下元素:

+------+------+ 
| v1 | v2 | 
+------+------+ 
| 1 | 2 | 
| 1 | 3 | 
| 1 | 4 | 
| 1 | 5 | 
| 1 | 6 | 
| 1 | 7 | 
| 1 | 8 | 
| 1 | 9 | 
| 2 | 1 | 
| 4 | 1 | 
| 5 | 1 | 
| 6 | 1 | 
| 7 | 1 | 
| 8 | 1 | 
| 9 | 1 | 
+------+------+ 

該表很大,有1540000個條目。要刪除多餘的條目(即得到一個只有(1,9)和(9,1)條目的表),我想用子查詢來做,但有沒有更好的方法來做到這一點?

回答

0

其實@Mark的方法也會起作用。我只是想出了另一種方法,並想知道我是否也能對此做出反饋。我測試了它,它似乎工作得很快。

SELECT v1,v2 FROM table WHERE v1<v2 UNION SELECT v2,v1 FROM table WHERE v1>v2; 

在這是正確的話,你總是可以創建一個新表:

CREATE TABLE newtable AS SELECT v1,v2 FROM edges WHERE v1<v2 UNION SELECT v2,v1 FROM edges WHERE v1>v2; 
0

警告:這些命令修改您的數據庫。確保您有備份副本,以便您可以根據需要再次恢復數據。

您可以添加v1必須小於v2的要求,這會減少您的存儲需求大約一半。您可以確保數據庫中的所有行均滿足此條件,並重新排序那些不相同的行,並在兩者都有時刪除其中一行。

這個查詢將插入,你必須例如任何遺漏行(5,1),而不是(1,5):

INSERT INTO table1 
SELECT T1.v2, T1.v1 
FROM table1 T1 
LEFT JOIN table1 T2 
ON T1.v1 = T2.v2 AND T1.v2 = T2.v1 
WHERE T1.v1 > T1.v2 AND T2.v1 IS NULL 

然後這個查詢刪除你不想要的行,像( 5,1):

DELETE table1 WHERE v1 > v2 

您可能需要更改代碼中添加此約束條件之前編程的其他位置。

+0

感謝您的時間。我只是想出了另一種方式並添加了它。我認爲這兩種方法基本上都使用相同的邏輯。你能讓我知道你對我的解決方案的看法嗎? – Legend 2010-05-13 19:42:29

+0

@傳奇:你的方法是創建一個新表。我的方法修改了現有表中的數據。我們都有相同的基本思想:對數據進行重新排序,使得「v1 2010-05-13 19:45:41