位置:首页 > SQL > SQL中LOCATE函数判断字段是否包含关键词的方法

SQL中LOCATE函数判断字段是否包含关键词的方法

时间:2026-08-12  |  作者:风起客  |  阅读:0

LOCATE返回0表示关键词未找到;它非布尔函数,而是返回首次出现位置(从1起),需显式判断>0;仅MySQL/MariaDB支持,跨库需改用POSITION、CHARINDEX等;默认不区分大小写,但受校对规则影响;无法利用B-tree索引,性能较差。

SQL中LOCATE函数如何判断字段是否包含关键词?

LOCATE 返回值为 0 表示关键词不存在

在 SQL 里,LOCATE 并不是布尔函数,它给出的结果是:关键词在字符串里第一次出现的位置,而且计数从 1 开始;如果没找到,返回的就是 0。也正因为如此,不能直接写成 WHERE LOCATE('abc', col) 来判断是否存在。原因很简单:一旦关键词正好出现在开头,LOCATE 会返回 1,而在大多数 SQL 引擎中,1 会被当成真;相反,如果结果是 0,那才表示根本没匹配到。

正确写法是显式比较:

SELECT * FROM table_name WHERE LOCATE('keyword', column_name) > 0;
  • LOCATE('a', 'abc') → 返回 1
  • LOCATE('x', 'abc') → 返回 0
  • LOCATE('', col) 在 MySQL 中返回 1(空串总被视作在位置 1 匹配),需额外规避

MySQL 和 MariaDB 支持,PostgreSQL 和 SQL Server 不支持

LOCATE 属于 MySQL/MariaDB 这套体系里的特有函数;如果换到 PostgreSQL,通常要改写成 POSITION('str' IN col) 或 STRPOS(col, 'str');到了 SQL Server,则需要使用 CHARINDEX('str', col)。它们的用途其实是一样的,都是返回匹配到的位置;如果没找到,就返回 0。其中 SQL Server 的 CHARINDEX 在未命中时同样返回 0,这一点和前面的行为保持一致。

  • MySQL:LOCATE('foo', col)
  • PostgreSQL:POSITION('foo' IN col) > 0 或 STRPOS(col, 'foo') > 0
  • SQL Server:CHARINDEX('foo', col) > 0
  • SQLite:用 INSTR(col, 'foo') > 0

跨数据库写法不可行,必须按目标引擎选函数。

区分大小写取决于字段 collation 或数据库配置

LOCATE 默认不区分大小写,前提是字段的校对规则(collation)是 utf8mb4_general_ci 或类似 _ci 结尾的。如果字段用了 _bin 或 _cs(case-sensitive)校对,则 LOCATE('A', 'apple') 会返回 0。

  • 查当前字段校对:执行 SHOW FULL COLUMNS FROM table_name LIKE 'column_name';
  • 临时强制不区分:可用 LOWER(column_name) 和 LOWER('keyword') 配合,但影响索引使用
  • 想走索引又大小写无关?得建函数索引(MySQL 8.0+)或冗余小写字段

性能隐患:LOCATE 无法利用普通 B-tree 索引

哪怕字段上有索引,LOCATE('kw', column) 依然触发全表扫描——因为这是“模式内任意位置匹配”,优化器无法跳过索引树遍历。

  • 前缀匹配(column LIKE 'kw%')能用索引
  • 后缀匹配(column LIKE '%kw')和中缀匹配(LIKE '%kw%')都不能,LOCATE 同理
  • 高频模糊搜索建议改用全文索引(MATCH ... AGAINST)或外部搜索引擎(如 Elasticsearch)

真正要查“是否包含”,且字段很长、数据量大时,别只图 LOCATE 写着顺手——先看执行计划 EXPLAIN,再决定要不要重构查询逻辑。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多