You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SQL实现记录的Unflatten(反扁平化)?

如何用SQL实现数据反扁平化(拆分逗号分隔值为多行)

可以实现,不同数据库有对应的SQL语法处理这类将逗号分隔字符串拆分为多行的需求,以下是几种主流数据库的实现方案:

MySQL(8.0及以上版本)

方案1:递归CTE

WITH RECURSIVE split_data AS (
    SELECT 
        IDV,
        `VALUES` AS original_val,
        SUBSTRING_INDEX(`VALUES`, ',', 1) AS split_val,
        SUBSTRING(`VALUES`, LENGTH(SUBSTRING_INDEX(`VALUES`, ',', 1)) + 2) AS remaining_val
    FROM your_table
    WHERE `VALUES` IS NOT NULL AND `VALUES` != ''
    UNION ALL
    SELECT 
        IDV,
        original_val,
        SUBSTRING_INDEX(remaining_val, ',', 1) AS split_val,
        SUBSTRING(remaining_val, LENGTH(SUBSTRING_INDEX(remaining_val, ',', 1)) + 2) AS remaining_val
    FROM split_data
    WHERE remaining_val IS NOT NULL AND remaining_val != ''
)
SELECT IDV, split_val AS `VALUES`
FROM split_data;

方案2:JSON_TABLE(更简洁)

SELECT 
    t.IDV,
    j.split_val AS `VALUES`
FROM your_table t
JOIN JSON_TABLE(
    CONCAT('["', REPLACE(t.`VALUES`, ',', '","'), '"]'),
    '$[*]' COLUMNS (split_val VARCHAR(255) PATH '$')
) j;

PostgreSQL

利用string_to_array将字符串转为数组,再用unnest展开数组为多行:

SELECT 
    IDV,
    unnest(string_to_array("VALUES", ',')) AS "VALUES"
FROM your_table;

SQL Server(2016及以上版本)

使用内置的STRING_SPLIT函数配合CROSS APPLY:

SELECT 
    t.IDV,
    s.value AS [VALUES]
FROM your_table t
CROSS APPLY STRING_SPLIT(t.[VALUES], ',') s;

Oracle(11g及以上版本)

通过REGEXP_SUBSTR结合CONNECT BY递归拆分:

SELECT 
    IDV,
    REGEXP_SUBSTR("VALUES", '[^,]+', 1, LEVEL) AS "VALUES"
FROM your_table
CONNECT BY 
    LEVEL <= REGEXP_COUNT("VALUES", ',') + 1
    AND PRIOR IDV = IDV
    AND PRIOR SYS_GUID() IS NOT NULL;

注意事项

  • 替换代码中的your_table为实际表名;
  • 若VALUES是数据库关键字,需用对应数据库的标识符包裹(如MySQL用反引号、SQL Server用方括号、PostgreSQL/Oracle用双引号),避免语法错误。

内容的提问来源于stack exchange,提问作者rholdberh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:02:54