MySQL LIKE IN()?
我目前的查询是这样的:
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
一个REGEXP 可能更有效率,但是你必须对它进行基准testing,例如
SELECT * from fiberbox where field REGEXP '1740|1938|1940';
保罗·迪克森的回答对我来说非常出色。 为了补充一点,下面是我对那些有兴趣使用REGEXP的人所观察到的一些事情:
使用通配符完成多个LIKEfilter:
SELECT * FROM fiberbox WHERE field LIKE '%1740 %' OR field LIKE '%1938 %' OR field LIKE '%1940 %';
使用REGEXPselect:
SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |1940 ';
REGEXP引号内和|之间的值 (OR)运营商被视为通配符。 通常,REGEXP将要求通配符expression式(例如(*)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';
-
将^放在值的前面表示行的开始。
-
在值后面放置$表示行结束。
-
放置(。*)的行为非常像%通配符。
-
的。 表示任何单个字符,除了换行符。 放置。 inside()用*(。*)添加一个重复模式,指示任意数量的字符,直到行尾。
有更有效的方法来缩小特定的匹配,但这需要更多的正则expression式的审查。 注:不是所有的正则expression式模式似乎在MySQL语句中工作。 你需要testing你的模式,看看有什么作用。
最后,要完成多个LIKE和NOT LIKEfilter:
SELECT * FROM fiberbox WHERE field LIKE '%1740 %' OR field LIKE '%1938 %' OR field NOT LIKE '%1940 %' OR field NOT LIKE 'test %' OR field = '9999';
使用REGEXPselect:
SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |^9999$' OR field NOT REGEXP '1940 |^test ';
或混合select:
SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 ' OR field NOT REGEXP '1940 |^test ' OR field NOT LIKE 'test %' OR field = '9999';
注意我将NOT设置在单独的WHEREfilter中。 我尝试了使用否定模式,前瞻性模式等等。 但是,这些expression式似乎没有产生预期的结果。 在上面的第一个例子中,我使用^ 9999 $来表示完全匹配。 这使您可以在同一expression式中添加与通配符匹配的特定匹配项。 但是,您也可以混合使用这些types的语句,如列举的第二个示例中所示。
关于performance,我对现有的桌子进行了一些小的testing,发现我的变化之间没有差异。 但是,我认为性能可能是更大的数据库,更大的领域,更大的logging数量和更复杂的filter的问题。
与往常一样,使用上面的逻辑是有道理的。
如果你想了解更多正则expression式,我build议www.regular-expressions.info作为一个很好的参考网站。
你可以创build一个内联视图或一个临时表,用你的值填充它,并发出这个:
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
但是,这可能会返回多行,类似于'1740, 1938'
fiberbox
,因此该查询可以更好地适应您:
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 )
正则expression式与值列表的方式
SELECT * FROM table WHERE field regexp concat_ws("|", "111", "222", "333");
对不起,在mysql中没有类似于LIKE IN
操作。
如果你想在没有连接的情况下使用LIKE操作符,你必须这样做:
(field LIKE value OR field LIKE value OR field LIKE value)
你知道,MySQL不会优化那个查询,FYI。
翻转操作数
'a,b,c' like '%'||field||'%'
这是正确的:
SELECT * FROM table WHERE field regexp concat_ws("|",( "111", "222", "333" ));
您可以在正则expression式的帮助下获得所需的结果。
SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]';
我们可以testing上面的查询请点击SQL小提琴
SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]';
我们可以testing上面的查询请点击SQL小提琴
只要注意任何人尝试REGEXP使用“LIKE IN”function。
IN允许你做:
field IN ( 'val1', 'val2', 'val3' )
在REGEXP中这是行不通的
REGEXP ' val1$| val2$| val3$ '
它必须是这样的:
REGEXP 'val1$|val2$|val3$'
只是一个小技巧:
我更喜欢使用变种RLIKE (与REGEXP完全相同的命令),因为它听起来更像自然语言,并且更短; 好吧,只有1个字符。
“R”的前缀是Reg。 经验,当然。