SELECT * FROM fiberbox f WHERE f.fiberBox LIKE '%1740 %' OR f.fiberBox LIKE '%1938 %' OR f.fiberBox LIKE '%1940 %'
我环顾四周,找不到类似于LIKE IN()的东西-我设想它的工作方式如下:
SELECT * FROM fiberbox f WHERE f.fiberbox LIKE IN('%140 %', '%1938 %', '%1940 %')
有什么想法吗?我只是以错误的方式思考问题-一些我从未见过的晦涩命令。
MySQL 5.0.77-community-log
#1 楼
REGEXP可能会更有效,但是您必须对其进行基准测试以确保,例如SELECT * from fiberbox where field REGEXP '1740|1938|1940';
评论
我喜欢这个答案-快速,简单,将所有“选项”都按我的意愿放在一行中(易于编辑)。在我定位的较小结果集上,性能完全没有降低。
–迈克尔·威尔士
09年7月14日在19:04
我的表格中有超过一百万行。 REGEX约0.0009,LIKE约0.0005。如果大于5个REGEX,则大约0.0012 ...
–DavidBélanger
2011-11-26 5:24
我遇到了一个问题,即REGEXP的运行速度过快,但是我需要REGEXP的灵活性,以使我的结果集缩小到LIKE所不能提供的范围。我想出了一个混合解决方案,在其中我同时使用了LIKE和REGEXP。尽管REGEXP部分足以为我提供正确的结果,但使用LIKE同样允许MySQL在不得不使用较慢的REGEXP标准之前大大减少结果集。
– mpen
2012年2月15日下午0:11
要从列中获取正则表达式值:(从中选择group_concat(myColumn分隔符'|')。)
– daVe
15年11月28日在1:05
添加到性能数据。在MySql 5.5中,在具有2.29亿行的表中,左第1个词锚了3个字符搜索:REGEXP:16s,LIKE:8.5s; 2个字词:REGEXP:22.1秒;喜欢:9.69; '^(hemoglobin | hematr?ocrit)。*'vs 3 term like:REGEXP:36.3,LIKE:9.59。
–杰西·克拉克(Jesse Clark)
16年3月11日在18:19
#2 楼
保罗·迪克森(Paul Dixon)的回答对我来说非常出色。此外,对于那些对使用REGEXP感兴趣的人,我观察到了一些东西:使用通配符实现多个LIKE过滤器:
SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
OR field LIKE '%1938 %'
OR field LIKE '%1940 %';
使用REGEXP替代方法:
SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |1940 ';
REGEXP引号内和|之间的值。 (OR)运算符被视为通配符。通常,REGEXP将需要通配符表达式,例如(。*)1740(。*)才能用作%1740%。
如果您需要对通配符的放置进行更多控制,请使用以下一些变体:
通过可控通配符放置来实现LIKE:
SELECT * FROM fiberbox WHERE field LIKE '1740 %'
OR field LIKE '%1938 '
OR field LIKE '%1940 % test';
使用:
SELECT * FROM fiberbox WHERE field REGEXP '^1740 |1938 $|1940 (.*) test';
在值前放置^表示行的开头。
在值后放置$表示行的末尾。
(。*)的行为与%通配符非常相似。
。表示任何单个字符,但换行符除外。将。
内的()放在*(。*)处会添加一个重复的模式,该模式指示到行末的任何数量的
字符。
有更有效的方法来缩小特定范围匹配,但这需要更多检查正则表达式。注意:并非所有的正则表达式模式都可以在MySQL语句中使用。您需要测试您的模式并查看其工作原理。
最后,要完成多个LIKE和NOT LIKE过滤器:
SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
OR field LIKE '%1938 %'
OR field NOT LIKE '%1940 %'
OR field NOT LIKE 'test %'
OR field = '9999';
使用REGEXP替代项:
SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |^9999$'
OR field NOT REGEXP '1940 |^test ';
或混合替代项:
SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 '
OR field NOT REGEXP '1940 |^test '
OR field NOT LIKE 'test %'
OR field = '9999';
注意我将NOT集合分开在哪里过滤。我尝试使用否定模式,前瞻性模式等。但是,这些表达式似乎未产生期望的结果。在上面的第一个示例中,我使用^ 9999 $表示完全匹配。这使您可以在同一表达式中添加具有通配符匹配项的特定匹配项。但是,您也可以混合使用这些类型的语句,如列出的第二个示例中所示。
关于性能,我对现有表进行了一些次要测试,发现我的变体之间没有差异。但是,我认为性能可能是更大的数据库,更大的字段,更大的记录数和更复杂的过滤器的问题。
一如既往,请使用上面的逻辑。
如果您想了解有关正则表达式的更多信息,建议您将www.regular-expressions.info作为一个很好的参考网站。
评论
请记住,值为NULL的字段与REGEXP不匹配。您可以使用IFNULL解决此问题。在哪里IFNULL(field,'')NOT REGEXP'1740 | 1938'
–user1026130
2013年6月18日18:25
@DanyMarcoux如果我想使用(。*),但它应该像FIELDNAME LIKE'%%'一样,如何与regexp一起使用,以便在传递空字符串时使用。它应该获取所有记录。
– shzyincu
16 Jul 28'14:09
不喜欢'%1940%'的WHERE字段或不喜欢'测试%'的字段将始终返回所有行。这可能是导致未产生您提到的预期结果的原因吗?
– Herbert Van-Vliet
2月29日下午21:35
#3 楼
您可以创建一个内联视图或一个临时表,并用您的值填充它并发出以下命令:SELECT *
FROM fiberbox f
JOIN (
SELECT '%1740%' AS cond
UNION ALL
SELECT '%1938%' AS cond
UNION ALL
SELECT '%1940%' AS cond
) с
ON f.fiberBox LIKE cond
但是,它可以为
fiberbox
返回多行类似于'1740, 1938'
,因此此查询可以更好地适合您:SELECT *
FROM fiberbox f
WHERE EXISTS
(
SELECT 1
FROM (
SELECT '%1740%' AS cond
UNION ALL
SELECT '%1938%' AS cond
UNION ALL
SELECT '%1940%' AS cond
) с
WHERE f.fiberbox LIKE cond
)
#4 楼
带值列表的正则表达式方式SELECT * FROM table WHERE field regexp concat_ws("|",
"111",
"222",
"333");
#5 楼
抱歉,在mysql中没有类似于LIKE IN
的操作。 如果要在没有联接的情况下使用LIKE运算符,则必须采用以下方式:
(field LIKE value OR field LIKE value OR field LIKE value)
您知道, MySQL不会优化该查询,仅供参考。
#6 楼
只需注意尝试使用REGEXP来使用“ LIKE IN”功能的任何人。IN允许您执行以下操作:
field IN (
'val1',
'val2',
'val3'
)
在REGEXP中,这赢了不起作用
REGEXP '
val1$|
val2$|
val3$
'
它必须像这样一行:
REGEXP 'val1$|val2$|val3$'
#7 楼
翻转操作数'a,b,c' like '%'||field||'%'
评论
当你有一些字段明确地等于例如。 grads'a','b','c'的枚举,但不包括ab,ac或bc的枚举创建表x(en enum('a,b,c')));插入x值('a'), ('b')en只是a或b通过翻转操作选择* from,x来执行此方法,其中像concat('%',en,'%')这样的'a,c'在SQL指令中可以更安全转义字符,例如$ ^等。
–user1883132
2012-12-15 15:05
这不是等效的,在一般情况下将不起作用。如果您知道该字段只能是a,b或c,则应使用字段IN(“ a”,“ b”,“ c”)。但是在一般情况下,这永远不能替换字段LIKE'%a%'或字段LIKE'%b%'或...,因为字段本身可以像魔术一样使'Magic'LIKE'%a%'变为真实,但表达式'a,b,c'就像'%magic%'一样。
– ADTC
17-10-21在1:34
#8 楼
这是正确的:SELECT * FROM table WHERE field regexp concat_ws("|",(
"111",
"222",
"333"
));
#9 楼
提示:我更喜欢使用变体RLIKE(与REGEXP完全相同的命令),因为它听起来更像自然语言,而且更短;好吧,只有1个字符。
“ R”前缀用于Reg。当然可以。
#10 楼
您可以在正则表达式的帮助下获得所需的结果。SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]';
我们可以测试以上查询,请单击SQL小提琴
SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]';
我们可以测试以上查询,请单击SQL小提琴
评论
这是不正确的正则表达式。 [...]是一个字符集,意味着该集中的任何字符都足以被视为匹配项。因此,任何具有数字'0、1、3、4、7、8、9或|的值竖线字符将与此匹配。
–马丁·彼得斯(Martijn Pieters)♦
18年7月5日在15:07
#11 楼
您也可以这样使用:SELECT * FROM fiberbox WHERE fiber IN('140 ', '1938 ', '1940 ')
评论
在哪里FIND_IN_SET(f.fiberbox,“ 1740,1938,1940”)FIND_IN_SET不接受%
之类的通配符