MySQL8.0版本中GROUP_CONCAT搭配DISTINCT去重不生效问题求助
问题原因分析
- DISTINCT与ORDER BY字段不匹配:MySQL规定
GROUP_CONCAT同时使用DISTINCT和ORDER BY时,ORDER BY的字段必须包含在DISTINCT的取值范围内。你的语句中DISTINCT作用于name字段,但排序用的是order_index,如果同一个name对应同一个spec_id下存在多个不同的order_index,MySQL会判定为不同的待拼接项,导致DISTINCT失效出现重复值。 - 字符串存在不可见字符:部分
name字段看起来值相同,实际包含空格、换行、全角/半角特殊符号等不可见字符,字符串实际值不一致,DISTINCT无法识别为重复项。 - 字符集排序规则异常:表或字段的排序规则设置不合理,会导致MySQL判定字符串相等的逻辑不符合预期,无法正常去重。
解决方案
方案1:拆分去重与拼接逻辑(最稳妥)
先通过子查询按spec_id+name分组实现去重,再在外层做排序拼接,避免GROUP_CONCAT中DISTINCT和ORDER BY的冲突:
SELECT GROUP_CONCAT(t.`name` ORDER BY t.order_idx ASC SEPARATOR '/') AS nameGroup FROM ( SELECT unit.spec_id, unit.`name`, MIN(unit.`order_index`) AS order_idx -- 同一个name取最小排序值,可根据业务换MAX FROM pms_spec_unit unit JOIN pms_spec spec ON spec.id = unit.spec_id WHERE spec.`status` = 1 GROUP BY unit.spec_id, unit.`name` ) t GROUP BY t.spec_id HAVING nameGroup LIKE '%年%'
方案2:清洗字符串后去重
如果是不可见字符导致的问题,先对name字段做清洗再拼接:
SELECT GROUP_CONCAT( DISTINCT TRIM(REPLACE(REPLACE(unit.`name`, '\r', ''), '\n', '')) ORDER BY unit.`order_index` ASC SEPARATOR '/' ) AS nameGroup FROM pms_spec_unit unit JOIN pms_spec spec ON spec.id = unit.spec_id WHERE spec.`status` = 1 GROUP BY unit.spec_id HAVING nameGroup LIKE '%年%'
排查验证方法
如果需要确认重复原因,可以先执行以下SQL查看指定spec_id下的name原始值和长度:
SELECT name, LENGTH(name) 字节长度, CHAR_LENGTH(name) 字符长度 FROM pms_spec_unit WHERE spec_id = 你要排查的spec_id AND name LIKE '%年%';
如果相同展示的name长度不一致,即可确认是不可见字符导致的问题。
内容的提问来源于stack exchange,提问作者lynn feng
相关产品推荐
相关产品推荐

