SQL 字符串函数如何实现字符串去重?

SQL 字符串函数如何实现字符串去重?
最新回答
蜕变

2020-08-01 00:08:21

SQL 中没有直接内置的字符串去重函数,但可通过拆分、去重、合并的组合操作实现,具体方法因数据库类型和需求场景而异。以下是针对不同场景的详细实现方案:

一、去除字符串中重复的字符(如 'aabbcc' → 'abc')

核心逻辑:将字符串拆分为单个字符,去重后重新合并。

  • PostgreSQL:使用 string_to_array 拆分字符串,unnest 展开为行,DISTINCT 去重,最后用 string_agg 合并。

    SELECT string_agg(DISTINCT c, '' ORDER BY c) AS dedupedFROM unnest(string_to_array('aabbcc', NULL)) AS c;

    结果:'abc'

  • MySQL 8.0+:需结合递归 CTE 或 JSON 函数模拟拆分过程,代码较复杂,建议优先在应用层处理。

二、去除字段中重复的子串(如 'apple,apple,banana' → 'apple,banana')

核心逻辑:按分隔符拆分子串,去重后重新拼接。

  • PostgreSQL

    SELECT string_agg(DISTINCT trim(unnest), ',' ORDER BY trim(unnest))FROM unnest(string_to_array('apple,apple,banana', ','));

    步骤

    string_to_array 按逗号拆分字符串。

    unnest 将数组展开为多行。

    trim 去除子串两端空格。

    DISTINCT 去重后,string_agg 按逗号重新拼接。

  • MySQL 8.0+:可通过存储过程或 JSON 函数模拟,但代码冗长,推荐在应用层处理或使用自定义函数(见下文)。

三、多行数据中对字符串字段去重(行级去重)

场景:从表中去除重复的字符串记录。方法:直接使用 DISTINCT 或 GROUP BY。

SELECT DISTINCT name FROM users;

SELECT name FROM users GROUP BY name;四、自定义函数实现通用去重(以 MySQL 为例)

需求:处理逗号分隔字符串的去重(如 'apple,apple,banana' → 'apple,banana')。实现步骤

  1. 创建辅助数字表:生成连续数字序列用于拆分字符串。
  2. 拆分子串:通过 SUBSTRING_INDEX 结合数字表逐个提取子串。
  3. 去重与拼接:使用游标遍历去重后的子串,重新拼接为字符串。

完整代码

DELIMITER $$CREATE FUNCTION dedup_string(input TEXT)RETURNS TEXTREADS SQL DATADETERMINISTICBEGIN DECLARE result TEXT DEFAULT ''; DECLARE current_word VARCHAR(255); DECLARE done INT DEFAULT 0; DECLARE cur CURSOR FOR SELECT DISTINCT TRIM(word) FROM ( SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(input, ',', numbers.n), ',', -1) word FROM (SELECT 1 n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) numbers WHERE numbers.n <= 1 + (LENGTH(input) - LENGTH(REPLACE(input, ',', ''))) ) t WHERE word != ''; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur; read_loop: LOOP FETCH cur INTO current_word; IF done THEN LEAVE read_loop; END IF; IF result = '' THEN SET result = current_word; ELSE SET result = CONCAT(result, ',', current_word); END IF; END LOOP; CLOSE cur; RETURN result;END$$DELIMITER ;

调用示例

SELECT dedup_string('apple,apple,banana'); -- 返回 'apple,banana'五、不同数据库的适用性总结
  • PostgreSQL:支持高级字符串函数(如 string_to_array、unnest、string_agg),处理此类问题更灵活。
  • MySQL:需依赖递归 CTE、JSON 函数或自定义函数,代码复杂度较高。
  • 通用建议

    简单场景优先使用数据库内置函数组合。

    复杂逻辑(如自定义分隔符、多级去重)建议在应用层处理。

核心思路:无论何种场景,字符串去重的本质均为 拆分 → 去重 → 合并,根据数据库特性选择合适工具即可。