直接用like配合count()可统计含特定字符的记录数,如select count() from users where email like '%@gmail.com%';需注意%通配任意长度字符、大小写默认不敏感、null值不匹配、%开头导致索引失效等问题。

直接用 LIKE 配合 COUNT(*) 就能查出包含特定字符的记录数,但要注意通配符、大小写和索引失效问题。
用 LIKE 查含字符的记录数
最常用也最直观的方式是 WHERE 字段名 LIKE '%字符%',搭配 COUNT(*) 统计数量。MySQL 默认不区分大小写(取决于字段的 collation),所以 '%abc%' 能匹配 'ABC'、'XaBcY' 等。
示例:统计 users 表中 email 字段含 @gmail.com 的用户数:
SELECT COUNT(*) FROM users WHERE email LIKE '%@gmail.com%';
-
%是通配符,代表任意长度字符(包括零个);想查以某字符开头,用'字符%';结尾则用'%字符' - 如果要查字面意义的
%或_,得用ESCAPE指定转义符,比如LIKE '%100\%' ESCAPE '\' - 注意:字段为
NULL的记录不会被LIKE匹配到,也不会计入COUNT(*)
REGEXP 更灵活但更慢
当需要模糊逻辑更复杂时(比如“含数字且含字母”“以 a 或 b 开头”),REGEXP 比 LIKE 强大,但执行效率明显更低,尤其在大数据量或无索引字段上。
示例:查 name 中含连续两个数字的记录数:
SELECT COUNT(*) FROM users WHERE name REGEXP '[0-9]{2}';
-
REGEXP默认区分大小写(受 collation 影响),如需忽略,加BINARY修饰或改用REGEXP_LIKE(..., ..., 'i')(MySQL 8.0.17+) - 正则表达式无法利用普通 B-tree 索引,全表扫描概率高;若频繁使用,考虑生成列 + 索引
- 简单子串查找别硬套正则,
LIKE更轻量、更易读、优化器更友好
大小写敏感场景怎么处理?
如果字段是 utf8mb4_general_ci 这类 case-insensitive collation,LIKE 和 = 都不区分大小写。要强制区分,有三个办法:
- 临时用
BINARY:WHERE BINARY name LIKE '%Java%'—— 注意这会让索引失效 - 换用 binary collation 比较:
WHERE name COLLATE utf8mb4_bin LIKE '%Java%' - 用
REGEXP配合'c'标志(MySQL 8.0.17+):WHERE name REGEXP_LIKE('Java', 'c')
真正需要大小写敏感查询时,建议建表时就选 utf8mb4_bin 或 utf8mb4_0900_as_cs(case-sensitive)collation,而不是运行时补救。
为什么 COUNT(*) 比 COUNT(字段) 更合适?
查“包含某字符的记录数”,目标是满足条件的行数,不是字段非空值个数。用 COUNT(字段) 会额外过滤掉该字段为 NULL 的行——而你用 LIKE 本来就不会命中 NULL,所以两者结果一样,但语义不清。
-
COUNT(*)明确表示“统计满足 WHERE 条件的行数”,是标准写法 -
COUNT(email)实际等价于COUNT(*)在这个场景下,但容易让人误以为你在统计非空 email 数量 - 性能上无差异,但可读性和意图传达差一截
真正容易被忽略的是:哪怕加了索引,LIKE '%xxx%' 也无法走索引前缀匹配,基本等于全表扫描。如果查询频次高、数据量大,得考虑倒排、全文索引或应用层缓存。











