如何使用 LIKE 通配符在列中搜索(不区分大小写)?

Posted

技术标签:

【中文标题】如何使用 LIKE 通配符在列中搜索(不区分大小写)?【英文标题】:How can I search (case-insensitive) in a column using LIKE wildcard? 【发布时间】:2011-02-22 00:53:52 【问题描述】:

我环顾了一些,没有找到我想要的东西,所以就这样吧。

SELECT * FROM trees WHERE trees.`title` LIKE  '%elm%'

这很好用,但如果树被命名为 Elm 或 ELM 等...

如何使 SQL 对这个通配符搜索不区分大小写?

我正在使用 mysql 5 和 Apache。

【问题讨论】:

如果您偶然发现此页面,但您的 MySql 设置确实可以处理 Elm 或 ELM 的此查询,并且您希望它区分大小写,请参阅BINARY,例如:***.com/questions/7857669/… 不依赖于字段/表的排序规则吗?像'ut8_general_CI' MySQL 的like 默认不区分大小写。 【参考方案1】:

我总是用 lower 解决这个问题:

SELECT * FROM trees WHERE LOWER( trees.title ) LIKE  '%elm%'

【讨论】:

MySQL 5 有 ILIKE 运算符吗? 尽管对于 %% 搜索它并不重要 :) @Col。 -- 诚然,这对于索引列来说不太理想,但它适用于已经存在的结构。我还发现不区分大小写的搜索更常见于无论如何都没有索引的列。 默认排序规则已经是 CI。所以,真正的问题不在这个特定的问题上。但它仍然是完美的 SO 风格的答案。 关于索引,如果你真的需要优化不区分大小写的搜索,那么你的表上会有一个额外的列,其中包含目标字段 ALREADY 映射为小写(或大写),然后您将在该列上创建一个索引。缺点是您现在有一个未标准化的更大数据库。但是您的搜索速度很快。【参考方案2】:
SELECT  *
FROM    trees
WHERE   trees.`title` COLLATE UTF8_GENERAL_CI LIKE '%elm%'

实际上,如果您将COLLATE UTF8_GENERAL_CI 添加到列的定义中,您可以省略所有这些技巧:它会自动工作。

ALTER TABLE trees 
 MODIFY COLUMN title VARCHAR(…) CHARACTER 
 SET UTF8 COLLATE UTF8_GENERAL_CI. 

这还将重建此列上的所有索引,以便它们可以用于不带前导 '%' 的查询

【讨论】:

也可以,这是不是更正确的做事方式?这有可能会被本地化,所以使用编码比使用低编码更好吗? 实际上,如果您将COLLATE UTF8_GENERAL_CI 添加到您的列定义中,您可以省略所有这些技巧:它会自动工作。 ALTER TABLE trees MODIFY COLUMN title VARCHAR(…) CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI。这还将重建此列上的所有索引,以便它们可以用于不带前导 '%' 的查询。 ALTER TABLE trees MODIFY COLUMN title VARCHAR(...) 这似乎是最好的方法,非常感谢...让 sql 完成工作 友情提醒,这是一个mysql的答案。如果您使用的是 PostgreSQL,ILike 是上述问题的解决方案。 这是正确的答案,因为您的原始整理是通用的,而不是 bin。【参考方案3】:

区分大小写在列/表/数据库排序规则设置中定义。您可以通过以下方式在特定排序规则下进行查询:

SELECT *
FROM trees
WHERE trees.`title` LIKE '%elm%' COLLATE utf8_general_ci

例如。

(将utf8_general_ci 替换为您认为有用的任何排序规则)。 _ci 代表不区分大小写

【讨论】:

在 MySQL 5.6 中我得到 ERROR 1273 (HY000): Unknown collat​​ion: 'utf_general_ci'。我猜这个排序规则已经从 MySQL 中删除了?不过utf8_general_ci 工作正常。 遇到了同样的问题。你要么必须修复你的COLLATE,要么做一个简单的技巧,比如this one(LOWER() 在比较之前你的两个字符串) 在 MySQL 5.6+ 或 MariaDB 10+ 中,您只需要在您的条件之前提供 COLLATE 指令。所以这行得通:SELECT * FROM products WHERE name COLLATE utf8_general_ci LIKE 'AB47TU';【参考方案4】:

这是一个简单的 LIKE 查询示例:

SELECT * FROM <table> WHERE <key> LIKE '%<searchpattern>%'

现在,使用 LOWER() 函数不区分大小写:

SELECT * FROM <table> WHERE LOWER(<key>) LIKE LOWER('%<searchpattern>%')

【讨论】:

其实这是一个很好的解决方案,尤其是当您遇到COLLATE 格式问题时【参考方案5】:

只需使用:

"SELECT * FROM `trees` WHERE LOWER(trees.`title`) LIKE  '%elm%'";

或使用

"SELECT * FROM `trees` WHERE LCASE(trees.`title`) LIKE  '%elm%'";

两个功能相同

【讨论】:

【参考方案6】:

我正在做类似的事情。

获取小写的值,其余的由 MySQL 完成

    $string = $_GET['string'];
    mysqli_query($con,"SELECT *
                       FROM table_name
                       WHERE LOWER(column_name)
                       LIKE LOWER('%$string%')");

对于 MySQL PDO 替代方案:

        $string = $_GET['string'];
        $q = "SELECT *
              FROM table_name
              WHERE LOWER(column_name)
              LIKE LOWER(?);";
        $query = $dbConnection->prepare($q);
        $query->bindValue(1, "%$string%", PDO::PARAM_STR);
        $query->execute();

【讨论】:

【参考方案7】:

我认为这个查询会进行不区分大小写的搜索:

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';

【讨论】:

在查询中使用 ILIKE 时,mysql 5.5 出现语法错误 这仅适用于 PostgreSQL;不是 MySQL。 postgresql.org/docs/current/static/functions-matching.html 如前所述,问题是关于 MySQL 的,而答案是关于 PostgreSQL 的,而且肯定不能与 MySQL 一起使用。我不反对它,但不禁想知道赞成票来自哪里......【参考方案8】:

使用ILIKE

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';

它对我有用!

【讨论】:

MySQL 确实支持 ILIKE。 这适用于 PostgreSQL,问题是关于 MySQL。【参考方案9】:

默认情况下,非二进制字符串比较(包括LIKE不区分大小写: https://dev.mysql.com/doc/refman/en/case-sensitivity.html

【讨论】:

【参考方案10】:

您不需要ALTER 任何表。只需在要使用通配符的实际 SELECT 查询之前使用以下查询:

    set names `utf8`;
    SET COLLATION_CONNECTION=utf8_general_ci;
    SET CHARACTER_SET_CLIENT=utf8;
    SET CHARACTER_SET_RESULTS=utf8;

【讨论】:

这是一个被严重低估的评论。它最普遍地解决了这个问题。我确实认为 alter table 语法也很重要,因为问题可能希望比较仅限于那一列。【参考方案11】:

在 mysql 5.5 中,like 运算符是不敏感的......所以如果你的 vale 是 elm 或 ELM 或 Elm 或 eLM 或任何其他,并且你使用 like '%elm%' ,它将列出所有匹配的值。

我不能说早期版本的mysql。

如果你进入 Oracle ,就像区分大小写一样,所以如果你输入类似 '%elm%' ,它只会为此而忽略大写。..

奇怪,但就是这样:)

【讨论】:

这并不完全正确。只有当排序规则设置为*_ci(代表“不区分大小写”)时,它才会这样工作。因为这恰好是所有支持的字符集的默认设置(问题show character set; 来检查这个) - 答案部分正确:-) 只有原因不正确。不区分大小写的不是运算符,而是默认排序规则。 是的,我同意你的看法。这取决于字符,如果您在生产中使用 *_ci 字符,那么唯一的选择是在 where 子句之前使用二进制【参考方案12】:
SELECT name 
       FROM gallery 
       WHERE CONVERT(name USING utf8) LIKE _utf8 '%$q%' 
       GROUP BY name COLLATE utf8_general_ci LIMIT 5 

【讨论】:

gallery 是表名,name 是表中的列, 请对您的代码添加一些说明,说明它的作用以及它如何提供帮助 - 这将在未来帮助其他人【参考方案13】:

您必须为您的表格设置正确的编码和排序规则。

表编码必须反映实际的数据编码。你的数据编码是什么?

要查看表编码,您可以运行查询SHOW CREATE TABLE tablename

【讨论】:

【参考方案14】:

当我想开发不区分大小写的搜索时,我总是在比较之前将每个字符串转换为小写

【讨论】:

【参考方案15】:

可以使用以下方法

 private function generateStringCondition($value = '',$field = '', $operator = '', $regex = '', $wildcardStart = '', $wildcardEnd = '')
        if($value != '')
            $where = " $field $regex '$wildcardStart".strtolower($value)."$wildcardEnd' ";

            $searchArray = explode(' ', $value);

            if(sizeof($searchArray) > 1)

                foreach ($searchArray as $key=>$value)
                    $where .="$operator $field $regex '$wildcardStart".strtolower($value)."$wildcardEnd'";
                

            

        else
            $where = '';
        
        return $where;
    

像下面这样使用这个方法

   $where =  $this->generateStringCondition($yourSearchString,  'LOWER(columnName)','or', 'like',  '%', '%');
  $sql = "select * from table $where";

【讨论】:

以上是关于如何使用 LIKE 通配符在列中搜索(不区分大小写)?的主要内容,如果未能解决你的问题,请参考以下文章

Sequelize - 不区分大小写

Python Pandas Regex:在列中搜索带有通配符的字符串并返回匹配项[重复]

MySQL中的Like和正则表达

08 使用通配符进行过滤 - like

通配符过滤正则表达式

《mysql必知必会》学习_第八章_20180730_欢