2024-02-04 08:00:03

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


你可以创建一个内联视图或临时表,用你的值填充它,然后发出这个:

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 ',所以这个查询更适合你:

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
        )

对不起,mysql中没有类似LIKE IN的操作。

如果你想在没有连接的情况下使用LIKE操作符,你必须这样做:

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

你知道,MySQL不会优化这个查询,供你参考。


REGEXP可能更有效,但您必须对其进行基准测试,例如。

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

保罗·迪克森的回答对我非常有效。为了补充这一点,以下是我观察到的对使用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';  

Use:

SELECT * FROM fiberbox WHERE field REGEXP '^1740 |1938 $|1940 (.*) test';

将^放在值的前面表示行开始。 在值之后放置$表示行结束。 放置(.*)的行为很像%通配符。 的。表示除换行符以外的任何单个字符。放置。 带有*(.*)的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过滤器中分离了NOT集。我尝试使用否定模式、向前看模式等等。然而,这些表达似乎没有产生预期的结果。在上面的第一个例子中,我使用^9999$来表示精确匹配。这允许您在同一个表达式中添加带有通配符匹配的特定匹配。但是,您也可以混合使用这些类型的语句,就像您在列出的第二个示例中看到的那样。

关于性能,我针对一个现有的表运行了一些小测试,发现我的变体之间没有差异。但是,我认为,对于更大的数据库、更大的字段、更大的记录计数和更复杂的过滤器,性能可能会成为一个问题。

像往常一样,使用上面的逻辑,因为它是有意义的。

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


翻转操作数

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

Regexp方法与值列表

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

这是正确的:

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

只要注意任何尝试REGEXP使用“LIKE IN”功能的人。

IN允许你做:

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

在REGEXP中,这是行不通的

REGEXP '
val1$|
val2$|
val3$
'

它必须像这样在一行中:

REGEXP 'val1$|val2$|val3$'

给你个小建议:

我更喜欢使用变体RLIKE(与REGEXP完全相同的命令),因为它听起来更像自然语言,而且更短;只有1个char。

“R”是Reg的前缀。当然是Exp。


正则表达式可以帮助你得到想要的结果。

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

我们可以测试上面的查询请点击SQL小提琴

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

我们可以测试上面的查询请点击SQL小提琴


你也可以这样用:

SELECT * FROM fiberbox WHERE fiber IN('140 ', '1938 ', '1940 ')

你也可以这样用:

 SELECT
    * 
FROM
    fiberbox f
    JOIN (
    SELECT
        substring_index( substring_index( '1740,1938,1940', ',', help_topic_id + 1 ), ',',- 1 ) AS sub_ 
    FROM
        mysql.help_topic 
    WHERE
        help_topic_id <(
            length( '1740,1938,1940' )- length(
            REPLACE ( '1740,1938,1940', ',', '' ))+ 1 
        ) AS b 
        ) ON f.fiberBox LIKE concat('%',
    b.sub_,
    '%')