使用LIKE在MySQL中查找重复记录

时间:2010-02-12 23:26:13

标签: sql mysql

我想在使用MySQL的客户表中按名称查找所有重复记录,包括那些完全不匹配的记录。

我知道我可以使用查询

SELECT id, name FROM customer GROUP BY name HAVING count(*) > 1;

查找完全匹配的所有行,但我想查找与LIKE子句匹配的所有重复行。例如,可能有一个名为“Mark's Widgets”的客户和另一个名为“Mark's Widgets Inc.”的客户。我希望我的查询能够找到这些重复项。

之类的东西
SELECT id, name AS name1 ... WHERE name1 LIKE CONCAT("%", name2, "%") ...

我知道这完全不正确,但这就是主意。这是有能力的架构:

mysql> describe customer;
+-----------------------------+--------------+------+-----+------------+----------------+
| Field                       | Type         | Null | Key | Default    | Extra          |
+-----------------------------+--------------+------+-----+------------+----------------+
| id                          | int(11)      | NO   | PRI | NULL       | auto_increment |
| name                        | varchar(140) | NO   |     | NULL       |                |
 ...

编辑:为了澄清,我想找到所有重复项,而不仅仅是一个特定客户名称的重复项。

5 个答案:

答案 0 :(得分:4)

很有可能做到这一点,但在你开始之前,你需要定义关于什么是匹配和什么不匹配的规则,没有它你就不能去任何地方。

例如,您可以忽略名称的第一个和最后3个字符并匹配中间字符,或者您可以选择更复杂的逻辑,但是没有实现您想要的魔术方法,您将不得不编码逻辑。无论您的选择是什么,它都需要在您开始之前和我们真正帮助之前进行定义。

这里没有mysql所以请原谅语法错误(如果有的话,它的t-sql语法),但我在考虑自我加入

SELECT
    t1.ID
FROM MyTable t1
LEFT OUTER JOIN MyTable t2
ON t1.name LIKE CONCAT('%', t2.name, '%')
group by t1.ID
HAVING count(*) > 1

答案 1 :(得分:0)

我认为这样可行,但根据我的经验,在ON中使用函数需要花费大量的时间来处理,特别是与LIKE运算符结合使用时。不过,它比交叉加入略胜一筹。

SELECT 
 cust1.id,
 cust1.name
FROM
 customer AS cust1
 INNER JOIN customer AS cust2 ON 
 (cust1.name LIKE (CONCAT('%',CONCAT(cust2.name,'%'))))
GROUP BY
 cust1.id,
 cust1.name
HAVING
 count(*) > 1

答案 2 :(得分:0)

这个怎么样?如果这有所不同,你可以用你的喜欢替换a.name = b.name。

Select a.id, b.id from customer a, customer b where a.name = b.name and a.id != b.id;

答案 3 :(得分:0)

我的回答是......

SELECT A . * 
FROM customer AS A, customer AS B
WHERE A.name LIKE CONCAT( '%', B.name, '%' ) 
AND A.name = B.name
GROUP BY A.id
HAVING COUNT( * ) >1

答案 4 :(得分:-1)

SELECT * FROM customer WHERE name LIKE "%Mark's Widgets%";

http://www.mysqltutorial.org/sql-like-mysql.aspx也应该帮助LIKE命令。

不确定为什么你需要使用CONCAT部分,所以这可能太简单了。