如何使用MySQL内置方法去除列中逗号分隔值的重复项?
MySQL 对逗号分隔日期列去重的实现方案
问题场景
你的表结构及数据如下:
id Dates 1 2024-02-19,2024-02-19 2 2024-02-19,2024-02-19,2024-02-26,2024-02-26,2024-02-26
需要将Dates列中的重复日期去除,得到唯一值用逗号分隔的结果:
id Dates 1 2024-02-19 2 2024-02-19,2024-02-26
解决方案
MySQL没有直接的内置函数可以一步完成这个需求,但可以结合内置函数或自定义函数实现,分版本说明:
1. MySQL 8.0+ 版本(推荐)
利用JSON_TABLE拆分字符串、STRING_AGG聚合去重,步骤如下:
WITH split_dates AS ( SELECT id, TRIM(jt.date_val) AS date_val FROM your_table JOIN JSON_TABLE( -- 将逗号分隔字符串转为JSON数组格式 CONCAT('["', REPLACE(Dates, ',', '","'), '"]'), '$[*]' COLUMNS(date_val VARCHAR(10) PATH '$') ) jt ) SELECT id, -- 去重后重新聚合为逗号分隔字符串 STRING_AGG(DISTINCT date_val, ',') AS Dates FROM split_dates GROUP BY id;
说明:
REPLACE + CONCAT把原字符串转成JSON数组格式,让JSON_TABLE可以拆分每行数据为独立的日期行TRIM处理日期前后可能存在的空格STRING_AGG(DISTINCT ...)对拆分后的日期去重并重新拼接
2. MySQL 5.x 版本
由于5.x版本不支持JSON_TABLE和STRING_AGG,可以通过自定义函数实现:
首先创建去重函数:
DELIMITER // CREATE FUNCTION remove_duplicate_dates(input_str VARCHAR(255)) RETURNS VARCHAR(255) DETERMINISTIC BEGIN DECLARE output_str VARCHAR(255) DEFAULT ''; DECLARE temp_date VARCHAR(10) DEFAULT ''; DECLARE pos INT DEFAULT 1; DECLARE total_parts INT DEFAULT LENGTH(input_str) - LENGTH(REPLACE(input_str, ',', '')) + 1; WHILE pos <= total_parts DO -- 拆分出单个日期 SET temp_date = SUBSTRING_INDEX(SUBSTRING_INDEX(input_str, ',', pos), ',', -1); -- 检查日期是否已在结果中,不在则添加 IF NOT FIND_IN_SET(temp_date, output_str) THEN SET output_str = CONCAT(output_str, IF(output_str = '', '', ','), temp_date); END IF; SET pos = pos + 1; END WHILE; RETURN output_str; END // DELIMITER ;
然后调用函数查询:
SELECT id, remove_duplicate_dates(Dates) AS Dates FROM your_table;
说明:
- 函数通过循环拆分每个日期,用
FIND_IN_SET判断是否已存在于结果字符串中,避免重复添加 - 注意如果
Dates列长度超过255,需要调整函数中VARCHAR的长度
内容的提问来源于stack exchange,提问作者LakshmiC
相关产品推荐
相关产品推荐

