2013-05-07 26 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, '.', ''), ',', '')