group by是否忽略大小写取决于字段collation,_ci结尾则天然忽略,_cs或_bin则区分;可用show full columns查看,临时方案用collate指定校对规则,长期应修改字段collation或建函数索引。

GROUP BY 本身不“主动忽略”大小写,是否忽略完全取决于字段的 collation —— 不是 MySQL 版本、不是 SQL 写法,而是字段定义里那个 Collation 值。
怎么看字段的 collation?
直接查,别猜:
-
SHOW FULL COLUMNS FROM user_activity LIKE '用户名';—— 看输出中Collation列的值 - 如果是
utf8mb4_0900_ai_ci或utf8mb4_general_ci(结尾带_ci),那GROUP BY 用户名就天然忽略大小写,不用加任何函数 - 如果是
utf8mb4_0900_as_cs或utf8mb4_bin(带_cs或_bin),那就严格区分,Alice和alice会被分到不同组
临时改:用 COLLATE 动态指定校对规则
不想改表结构,又想这次查询就忽略大小写,最轻量的写法是:
SELECT 用户名, COUNT(*) FROM user_activity GROUP BY 用户名 COLLATE utf8mb4_0900_ai_ci;
注意两点:
-
COLLATE必须紧跟在列名后,不能写成GROUP BY COLLATE utf8mb4_0900_ai_ci 用户名 - 如果字段类型是
BINARY或用了BINARY前缀,COLLATE会被忽略 - 不同 MySQL 版本支持的 collation 名称略有差异,先执行
SHOW COLLATION LIKE 'utf8mb4%ai%';确认可用项
长期方案:改字段 collation 或建函数索引
如果业务上始终需要忽略大小写分组,优先改字段定义:
ALTER TABLE user_activity MODIFY COLUMN 用户名 VARCHAR(255) COLLATE utf8mb4_0900_ai_ci;
如果无法改表(比如权限受限),再考虑函数索引:
- MySQL 8.0+ 支持:
CREATE INDEX idx_username_lower ON user_activity (LOWER(用户名)); - 之后才能安全用:
GROUP BY LOWER(用户名),否则LOWER(用户名)会让普通索引失效 - PostgreSQL 要对应建表达式索引:
CREATE INDEX idx_username_lower ON user_activity ((LOWER(用户名)));
别漏掉 NULL 和空字符串
GROUP BY 默认把所有 NULL 归为一组,但 ''(空字符串)和 NULL 是两回事。如果业务上认为它们等价,必须显式合并:
SELECT COALESCE(NULLIF(用户名, ''), 'unknown') AS norm_name, COUNT(*) FROM user_activity GROUP BY COALESCE(NULLIF(用户名, ''), 'unknown');
这个细节容易被跳过,线上数据一旦混入 NULL 和 '',统计结果就会偏高或漏分组。










