MySQL中如何对列的部分结果使用DISTINCT?实际案例求解
解决MySQL中DISTINCT去重无效的问题
嘿,我看你遇到了个有点坑的问题——明明用了DISTINCT,但groupname还是出现重复条目,比如Acetone_Sol多次返回。其实这种情况大多不是DISTINCT本身的问题,而是数据里藏着你看不到的差异,咱们一步步来解决:
第一步:排查重复的真实原因
首先得搞清楚为什么看起来相同的字符串会被MySQL当成不同的条目,常见的两个原因:
1. 存在隐藏空格或特殊字符
比如有的Acetone_Sol末尾可能多了个空格,或者中间有看不见的制表符,肉眼完全分辨不出来,但MySQL会认为是不同的值。你可以用这个SQL来验证:
SELECT groupname, CHAR_LENGTH(groupname) FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%' GROUP BY groupname, CHAR_LENGTH(groupname) HAVING COUNT(*) > 1;
如果看到同一个“看起来相同”的groupname对应不同的长度,那肯定是有隐藏字符了。
2. 大小写差异导致的
如果你的数据库排序规则是区分大小写的(比如utf8_bin),那Acetone_Sol和acetone_sol会被当成不同的字符串。可以用这个SQL查看二进制形式的差异:
SELECT groupname, BINARY groupname FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%' GROUP BY groupname, BINARY groupname HAVING COUNT(*) > 1;
二进制结果不一样的话,就是大小写或者字符编码的问题。
第二步:针对性解决去重问题
根据上面排查出的原因,咱们用对应的方法处理:
情况1:有隐藏空格/特殊字符
直接清洗数据,去除多余的空格和特殊字符:
- 如果你只需要去除前后空格,用
TRIM()就够了:
SELECT DISTINCT TRIM(groupname) AS cleaned_groupname FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%';
- 如果中间也有空格,用
REGEXP_REPLACE把所有空格替换掉:
SELECT DISTINCT TRIM(REGEXP_REPLACE(groupname, '\\s+', '')) AS cleaned_groupname FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%';
情况2:大小写差异
统一字符串的大小写,或者分组时忽略大小写:
- 统一转成小写(或大写)输出:
SELECT DISTINCT LOWER(groupname) AS normalized_groupname FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%';
- 要是想保留原字符串的大小写,只需要去重的话,可以用
GROUP BY结合聚合函数取第一个出现的条目:
SELECT MIN(groupname) AS unique_groupname FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%' GROUP BY LOWER(groupname);
替代方案:用GROUP BY直接去重
其实GROUP BY本身就有去重的效果,有时候比DISTINCT更直观,你也可以试试这个写法:
SELECT groupname FROM custom_quotes.compatibility_rule WHERE groupname LIKE '%_Sol%' GROUP BY groupname;
如果这样还是有重复,那肯定是数据里有隐藏差异,回到第一步排查就行。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

