如何使用 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 collation: '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 通配符在列中搜索(不区分大小写)?的主要内容,如果未能解决你的问题,请参考以下文章