MySQL SELECT LIKE或REGEXP以在一条记录中匹配多个单词


73

领域tablename包含“ Stylus Photo 2100”并带有以下查询

SELECT `name` FROM `table` WHERE `name` LIKE '%Stylus 2100%'

我没有结果。我当然会搜寻

SELECT `name` FROM `table` WHERE `name` LIKE '%Photo 2100%'

如何通过搜索“ Stylus 2100”选择记录?

谢谢


警告:这个问题是关于两个单词按特定顺序出现的。大多数答案不允许匹配“ 2100手写笔”。
瑞克·詹姆斯

Answers:


118

好吧,如果您知道单词的顺序..您可以使用:

SELECT `name` FROM `table` WHERE `name` REGEXP 'Stylus.+2100'

您也可以使用:

SELECT `name` FROM `table` WHERE `name` LIKE '%Stylus%' AND `name` LIKE '%2100%'

谢谢,这样我不会得到“ HP Laserjet 2100”。抱歉,如果我的例子不是最好的。
Alessio

1
回答者之一在此处比较了LIKE / REGEX的性能,发现LIKE表现更好,仅供参考:stackoverflow.com/questions/1127088/mysql-like-in
Amalgovinus

@Amalgovinus感谢您的链接,我不会这样想。它的好知道:)
SERPRO

如果我有3个单词怎么办?
弗罗林

第一个查询中的@Florin.+指示手写笔和2100之间的任何字符(1个或多个),如果您想添加EPSON,它将EPSON.+'Stylus.+2100在第二个查询中只需要AND在WHERE子句中添加新
字符

29

我认为最好的解决方案是使用正则表达式。它是最干净的,而且可能是最有效的。所有常用的数据库引擎都支持正则表达式。

在MySql中有RLIKE运算符,因此您的查询将类似于:
SELECT * FROM buckets WHERE bucketname RLIKE 'Stylus|2100'
我对regexp的了解不是很强,所以我希望表达式可以。

编辑
RegExp应该是:

SELECT * FROM buckets WHERE bucketname RLIKE '(?=.*Stylus)(?=.*2100)'

有关MySql regexp支持的更多信息:http :
//dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp


这正则表达式就不一样了:它得到任何含有要么“笔”或“2100”,不一定是两者兼而有之。
Jeff DQ 2013年

我已经改善了RegExp
Ondrej Bozek 2014年

1
我正在寻找仅使用regexp的解决方案,而这个技巧做到了^^,
velop

通过|像这样在2()之间添加a ,RLIKE '(?=.*Stylus)|(?=.*2100)'将得到单独的结果->>仅具有手写笔的行,仅具有2100的行或具有两者的行……但不一定同一行中的2…

你有尝试过吗?从未听说MySql regex支持环视。
泡泡泡泡

18

您可以将每个空格替换为 %

SELECT `name` FROM `table` WHERE `name` LIKE '%Stylus%2100%'

谢谢,但是这样,如果我搜索“ Photo Stylus 2100”,我就不会知道
Alessio Firenze'2

1
哈哈!好的,没有在“如何通过搜索'Stylus 2100'选择记录的问题”中指定该要求?
mdprotacio

我知道这个问题很古老,但这不是最有效的解决方案吗?据我所知,这将匹配Photo Stylus 2100。它将匹配,anything然后是Stylusanything然后是,2100然后是anything。如果有人不同意,请告诉我原因,因为这意味着我从根本上误解了类似表达式的内容。
RTF

1
@RTF我有点晚了,但是%在Regex中就像+,而不是*。它与某物匹配,没有什么匹配,因此不匹配Photo Stylus 2100但会匹配Photo Stylus 2100x
tjbp

@tjbp-错误。 LIKE's %匹配空字符串。因此,它基本上与相同RLIKE's .*。梅尔文的答案不变。阿莱西奥的第一句话是错误的。测试很简单: SELECT 'Photo Stylus 2100' LIKE '%Stylus%2100%';返回1(表示true)。
瑞克·詹姆斯

6

正确的解决方案是全文搜索(如果可以使用的话)https://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

这几乎可以满足您的要求:

SELECT * FROM buckets WHERE bucketname RLIKE '(Stylus|2100)+.*(Stylus|2100)+';

SELECT * FROM buckets WHERE bucketname RLIKE '(Stylus|2100|photo)+.*(Stylus|2100|photo)+.*(Stylus|2100|photo)+.*';

但这也将与“ 210021002100”匹配,但效果并不理想。



0

假设您的搜索是stylus photo 2100。请尝试使用以下示例RLIKE

SELECT * FROM `buckets` WHERE `bucketname` RLIKE REPLACE('stylus photo 2100', ' ', '+.*');

编辑

另一种方法是在语句中使用FULLTEXT索引bucketnameMATCH ... AGAINST语法SELECT。所以要重写上面的例子...

SELECT * FROM `buckets` WHERE MATCH(`bucketname`) AGAINST (REPLACE('stylus photo 2100', ' ', ','));

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.