2013-05-07 81 views
5

查詢的目標還在於找到可能重名的錯誤名稱。例如:向MySQL內部連接添加多個條件

International Group Inc.必須找到爲International, Group Inc

重複爲了實現這個使用的下一個查詢:

SELECT C.id, 
     C.name, 
     C.address, 
     C.city_id 
FROM company C 
     INNER JOIN (SELECT name 
        FROM company 
        GROUP BY name 
        HAVING Count(id) > 1) D 
       ON Replace(Replace(C.name, '.', ''), ',', '') = 
        Replace(Replace(D.name, '.', ''), ',', '') 

它工作得很好,結果就在40 secs但添加像AND C.city_id='4'等額外條件需要額外的分鐘或更多;這仍然是可以接受的,但不是可取的

當我嘗試添加另一個條件來找出名稱中只包含特定字符串的公司的重複項時,出現真正的問題,使用此條件AND C.name LIKE '%International%',這只是不返回任何結果。

有人能幫我弄清楚我做錯了什麼嗎?

感謝

+0

不幸的是,我不認爲你可以在這種情況下有效地使用索引 - 儘管1分鐘+似乎非常緩慢。 – Strawberry 2013-05-07 12:26:48

回答

6

因爲你在一個函數的結果結合在一起的,查詢不能使用任何索引。此外,在所有行上執行REPLACE()的成本可能不可忽略。

我建議你先添加接收字符串的「簡裝版」的索引列,然後運行與此列聯接查詢:

ALTER TABLE company ADD COLUMN stripped_name VARCHAR(50); 
ALTER TABLE company ADD INDEX(stripped_name); 
UPDATE TABLE company SET stripped_name = REPLACE(REPLACE(name, '.', ''), ',', '') ; 

運行UPDATE可能需要而第一次,但你也可以在company上設置ON UPDATEON INSERT觸發器,以便stripped_name得到填充和即時更新。

+0

這是一個好主意 - 顯而易見(儘管我沒有想到它!) – Strawberry 2013-05-07 12:28:06

+0

這個解決方案確實提高了性能,但是在使用公司名稱中的特定字符串時仍然無法獲得結果'AND E.stripped_name LIKE'%International%''。爲什麼會這樣? – gustyaquino 2013-05-07 12:48:21

+1

@gustyaquino你確定有一個匹配的行嗎?您也可能正在使用區分大小寫的排序規則。請向我們展示您的表的完整結構('SHOW CREATE TABLE company;') – RandomSeed 2013-05-07 12:54:50

0

嘗試從TMP表開始,因爲公司的foreach排TMP表將被創建:

SELECT C.id, 
     C.name, 
     C.address, 
     C.city_id 
FROM (SELECT name 
        FROM company 
        GROUP BY name 
        HAVING Count(id) > 1) D 
INNER JOIN company C  
       ON Replace(Replace(C.name, '.', ''), ',', '') = 
        Replace(Replace(D.name, '.', ''), ',', '')