MySQL拆分字符串为单个值:将table_string表数据拆分存储至新表
嘿,这个需求核心就是把表中按逗号分隔的Name和ADD列,按相同位置拆分后一一配对,同时保留原ID,最后存到新表对吧?下面我给你整理了几种主流数据库的实现方案,直接就能套用:
1. SQL Server 实现方案
SQL Server 2016+支持STRING_SPLIT,但要注意这个函数默认不带序号,所以得用ROW_NUMBER()给拆分后的每个值标记位置,再通过ID和位置关联Name和ADD的拆分结果:
-- 先创建新表(如果需要提前定义结构) CREATE TABLE NewTable ( ID INT, Name VARCHAR(50), ADD VARCHAR(50) ); -- 拆分并插入数据到新表 WITH SplitNames AS ( SELECT ID, value AS NameItem, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT NULL)) AS ItemIndex FROM table_string CROSS APPLY STRING_SPLIT(Name, ',') ), SplitAdds AS ( SELECT ID, value AS AddItem, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT NULL)) AS ItemIndex FROM table_string CROSS APPLY STRING_SPLIT(ADD, ',') ) INSERT INTO NewTable (ID, Name, ADD) SELECT sn.ID, sn.NameItem, sa.AddItem FROM SplitNames sn JOIN SplitAdds sa ON sn.ID = sa.ID AND sn.ItemIndex = sa.ItemIndex;
注意:
STRING_SPLIT的ORDER BY (SELECT NULL)依赖SQL Server内部的拆分顺序,如果你需要严格保证逗号分隔的顺序,建议用基于XML的拆分方式,不过大部分场景下这个方式足够用。
2. MySQL 实现方案
MySQL 8.0+可以用递归CTE生成序列,配合SUBSTRING_INDEX拆分每个位置的元素;低版本则需要用数字辅助表:
8.0+ 版本(递归CTE)
-- 创建新表 CREATE TABLE NewTable ( ID INT, Name VARCHAR(50), `ADD` VARCHAR(50) ); -- 拆分并插入 WITH RECURSIVE seq AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM seq WHERE n < (SELECT MAX(LENGTH(Name) - LENGTH(REPLACE(Name, ',', '')) + 1) FROM table_string) ) INSERT INTO NewTable (ID, Name, `ADD`) SELECT t.ID, TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(t.Name, ',', s.n), ',', -1)) AS NameItem, TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(t.`ADD`, ',', s.n), ',', -1)) AS AddItem FROM table_string t JOIN seq s ON s.n <= LENGTH(t.Name) - LENGTH(REPLACE(t.Name, ',', '')) + 1 ORDER BY t.ID, s.n;
低版本(数字辅助表)
如果你的MySQL版本低于8.0,没有递归CTE,可以先创建一个存1到N的数字表(比如1到100),再用同样的SUBSTRING_INDEX逻辑关联查询即可。
3. PostgreSQL 实现方案
PostgreSQL里可以用string_to_array把字符串转成数组,再用unnest ... WITH ORDINALITY获取每个元素的位置,最后关联ID和位置:
-- 创建新表(注意ADD是关键字,这里用add_col代替避免语法错误) CREATE TABLE new_table ( id INT, name VARCHAR(50), add_col VARCHAR(50) ); -- 拆分并插入 WITH split_data AS ( SELECT t.id, unnest(string_to_array(t.name, ',')) WITH ORDINALITY AS (name_item, idx), unnest(string_to_array(t.add, ',')) WITH ORDINALITY AS (add_item, idx2) FROM table_string t ) INSERT INTO new_table (id, name, add_col) SELECT id, name_item, add_item FROM split_data WHERE idx = idx2 ORDER BY id, idx;
内容的提问来源于stack exchange,提问作者synccm2012
相关产品推荐
相关产品推荐

