2009-07-14 105 views
204

我当前的查询看起来是这样的:MySQL LIKE IN()?

SELECT * FROM fiberbox f WHERE f.fiberBox LIKE '%1740 %' OR f.fiberBox LIKE '%1938 %' OR f.fiberBox LIKE '%1940 %' 

我做了一些环顾四周,找不到类似于像()什么 - 我想象它的工作是这样的:

SELECT * FROM fiberbox f WHERE f.fiberbox LIKE IN('%140 %', '%1938 %', '%1940 %') 

任何想法?我只是在想这个问题的错误的方式 - 一些模糊的命令我从来没有见过。

的MySQL 5.0.77社区日志

+0

'WHERE FIND_IN_SET(f.fiberbox, “1740,1938,1940” )` – 2017-10-30 20:21:27

回答

328

A REGEXP可能效率更高,但您必须对其进行基准测试以确保

SELECT * from fiberbox where field REGEXP '1740|1938|1940'; 
+2

我喜欢这个答案 - 快速,简单,像我想要的(易于编辑)在一行中获得所有“选项”。在我定位的小型结果集中,性能完全没有下降。 – 2009-07-14 19:04:21

+4

有谁在大数据集上对此进行基准测试? – Ascherer 2011-08-18 17:42:22

+37

我的表超过100万行。 REGEX约为0.0009,LIKE约为0.0005。如果超过5 REGEX,大约0.0012 ... – 2011-11-26 05:24:20

13

您可以创建一个内嵌视图或临时表,你值填充它,并发出这样的:

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 
     ) 
+1

+1,直到现在还没有理解JOIN语句。 – Zack 2009-07-14 19:12:45

7

对不起,没有类似于的操作在mysql中。

如果要使用LIKE操作没有加入,你就必须做这样说:

(field LIKE value OR field LIKE value OR field LIKE value) 

你知道,MySQL不会优化该查询,仅供参考。

136

保罗狄克逊的答案为我工作出色。要添加到这一点,这里有一些事情,我对那些有兴趣使用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%%至工作。

如果您需要在通配符的位置更多的控制,使用其中的某些变种:

具有受控通配符布局完成这样:

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'; 
  • 在配售值前面^表示线的开始。

  • 值后放置$表示行尾。

  • 配置(。*)的行为与%通配符非常相似。

  • The。表示除换行符外的任何单个字符。放置。 inside()用*(。*)添加一个重复模式,指示字符的任何数字 直到行尾。

有更有效的方法来缩小特定的匹配,但这需要更多的正则表达式审查。注意:并非所有正则表达式模式似乎都可以在MySQL语句中使用。你需要测试你的模式,看看有什么作用。

最后,为了实现多似与不似过滤器:

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'; 

通知我分离未设置在一个单独的WHERE过滤器中。我尝试了使用否定模式,前瞻模式等等。但是,这些表达似乎并没有产生预期的结果。在上面的第一个例子中,我使用^ 9999 $来表示完全匹配。这允许您在同一表达式中添加与通配符匹配的特定匹配项。但是,您也可以混合使用这些类型的语句,如列举的第二个示例中所示。

关于性能,我对现有的表进行了一些小测试,结果发现我的变化没有区别。不过,我认为性能可能是更大的数据库,更大的领域,更大的记录数量和更复杂的过滤器的问题。

一如既往,使用上面的逻辑是有道理的。

如果你想了解更多关于正则表达式,我建议www.regular-expressions.info作为一个很好的参考网站。

3

翻转操作数

'a,b,c' like '%'||field||'%' 
8

正则表达式的方式与值列表

SELECT * FROM table WHERE field regexp concat_ws("|", 
"111", 
"222", 
"333"); 
1

这将是正确的:

SELECT * FROM table WHERE field regexp concat_ws("|",(
"111", 
"222", 
"333" 
)); 
2

只要注意给任何人试图在REGEXP使用“喜欢“功能。

允许您做到:

field IN (
'val1', 
'val2', 
'val3' 
) 

在REGEXP这是不行的

REGEXP ' 
val1$| 
val2$| 
val3$ 
' 

它是在这样一行:

REGEXP 'val1$|val2$|val3$' 
1

只是一个小提示:

我更喜欢用变种RLIKE(与REGEXP完全相同的命令),因为它听起来更像自然语言,并且更短;好吧,只有1个字符。

“R”前缀用于Reg。 Exp,当然。

1

您可以在Regular Expressions的帮助下获得想要的结果。

SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]'; 

我们可以测试上面的查询请点击SQL fiddle

SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]'; 

我们可以测试上面的查询请点击SQL fiddle