MySQL实现字符串分割与批量拆分插入

何川
何川
发布时间:2026-10-15| 3人浏览过
原创

由于MySQL未内置直接切割字符串的Split函数,在处理包含大量分隔符的脏数据时,往往需要借助自定义函数与存储过程配合。本文介绍一种基于SUBSTRING_INDEX函数计算索引位置、结合循环结构将单条长记录拆解为多条明细记录的实操方案,适用于数据清洗及ETL场景。

核心原理:利用 SUBSTRING_INDEX 模拟分割

MySQL 中强大的 SUBSTRING_INDEX 函数可以作为分割的基础。它可以根据指定的分隔符和出现次数,截取字符串的一部分。要实现类似 Split 的效果,关键在于精准计算出每个子串的起始位置和长度。CHAR_LENGTH 函数用于获取字符串字符数,通过对比不同分割点的长度差,即可确定单个元素的长度。

以下是一个典型的自定义函数 str_for_substr,其目的是从以特定分隔符(如 “###”)连接的字符串中提取第 N 个元素。

第一步:创建取数自定义函数

目的:根据传入的索引值 num 和原始字符串 str,提取出对应的子串片段。 入口:MySQL 命令窗口或 Navicat 等客户端编辑器。 重要参数:

  • num:要取出的元素索引,从 0 开始计数。
  • str:待分割的源字符串。
drop function if exists str_for_substr;
CREATE
    DEFINER = `root`@`%` FUNCTION `str_for_substr`(`num` int, `str` varchar(5000))
    RETURNS varchar(100) no sql
BEGIN
    /*函数功能: 把带逗号的字符串分割取出
        参数: num 要取出的字符串的索引值, 以0开始
                    str 以逗号分割的字符串
        扩展: 将###替换成其他符合,即可完成不同分隔符拆分字符串,亦可以把分隔符作为参数
  */
    SET @str_for_substr =
            SUBSTRING(
                    SUBSTRING_INDEX(str, '###', num + 1),
                    CASE num
                        WHEN 0 THEN
                                CHAR_LENGTH(
                                        SUBSTRING_INDEX(str, '###', num)
                                    ) + 1
                        ELSE
                                CHAR_LENGTH(
                                        SUBSTRING_INDEX(str, '###', num)
                                    ) + 4
                        END,
                    CASE num
                        WHEN 0 THEN
                                CHAR_LENGTH(
                                        SUBSTRING_INDEX(str, '###', num + 1)
                                    ) - CHAR_LENGTH(
                                        SUBSTRING_INDEX(str, '###', num)
                                    )
                        ELSE
                                CHAR_LENGTH(
                                        SUBSTRING_INDEX(str, '###', num + 1)
                                    ) - CHAR_LENGTH(
                                        SUBSTRING_INDEX(str, '###', num)
                                    ) - 1
                        END
                );
    RETURN @str_for_substr;
END;

第二步:构建存储过程实现批量处理

目的:遍历源表中的每一行数据,识别其中包含的分隔符数量,循环调用上述函数并将拆分后的数据逐行写入目标表中。 入口:MySQL 存储过程管理器或 SQL 脚本。 完成状态:运行无报错,且目标表 test1 中的数据量等于所有源数据拆分后产生的总行数。

drop procedure if exists split_str;
CREATE
    DEFINER = `root`@`%` PROCEDURE `split_str`()

BEGIN

    DECLARE cnt int default 0;
    DECLARE num int default 0;
    DECLARE i int default 0;
    DECLARE j int default 0;
    declare str varchar(4000);

#   统计当前截取字段表的数据量
    select count(1) into cnt from test;
#   循环查询每一条数据,此处可以换成游标处理
    while i<= cnt do
        select query_knowledge_list_string into str from test limit i,1;
#       查询每条数据###出现的次数
        SET num = (LENGTH(str) - LENGTH(REPLACE(str, '###', ''))) / 3;
        while j <= num do
#               循环插入截取后的数据
                INSERT INTO test1 (knowledge_name, subject_name, grade_name)
                select str_for_substr(j,str), subjectName, grade_name
                from test limit i,1;
            set j = j + 1;
            end while;
#       循环值归零
        set j = 0;
        set i = i + 1;
        end while;
END;

在实际应用前,建议对涉及的表数据进行备份,因为涉及全表循环插入操作,在大数据量下可能会产生性能瓶颈。如果源表数据量极大,建议将外层循环改为游标(Cursor)方式处理。

进阶技巧:简单字段的非标准符号分割

除了拆分复杂的多字段列表,日常处理中还经常遇到需要在字符串前剔除特定前缀的场景。例如,在同步 Hive 数仓数据时,字段前常混入带有编号的顿号(如 “1、语文”),而业务只需要保留内容部分。

由于 MySQL 没有直接的 Split 返回数组的功能,我们可以组合使用 INSTR() 和 SUBSTR() 来动态定位截取点。首先检查分隔符是否存在,若存在则通过偏移量跳过前缀进行截取。

以下是该场景下的标准 SQL 写法:

select 
year,
case when INSTR(subtype,'、')>0 then SUBSTR(subtype,INSTR(subtype,'、')+1)
else subtype END subtype
from 
xxx_table_name

执行结果会自动过滤掉顿号及其前面的数字编码,使数据更加规整。

综上,通过自定义函数配合存储过程,可以有效解决 MySQL 环境下的复杂字符串切片需求;而对于简单的单字段前缀清理,则推荐使用 INSTR 结合 SUBSTR 实现轻量级处理。以上就是关于MySQL字符串分割功能的详细内容,更多关于MySQL高级应用及数据清洗的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。