惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 大汪的数据之路

数据码农马年大吉 BI报表及可视化分析类工具使用经验总结(下) BI报表及可视化分析类工具使用经验总结(上) 基于Python实现自动化微信通知和预警 Chat2DB测试体验 常用数据管理工具与平台汇总 OneID系统建设实践总结 网易有数BI使用总结 网易NDH大数据平台使用经验 版本管理总结 程序自动化vs人工手动处理 SQL开发总结 数据平台使用经验 数据团队运维值班任务简介 Python环境安装、管理与部署 windows获取kerberos认证 SQL动态长度行列转置 ODI Scenario 场景 Oracle KEEP 分析函数
字符串分割并展开成表格的SQL实现方法
大汪的数据之路 · 2026-01-20 · via 博客园 - 大汪的数据之路

一、场景案例

在数据开发类项目中,常常会遇到需要将字符串进行切割并展开成表格的场景,如以下两种常见的案例:

  1. 标签类型数据:如将员工标签类型的数据
    - 技能:Java、Spring、微服务、项目管理
    - 项目经验:电商、金融、教育
    - 工作风格:#执行力强 #跨部门协作 #数据驱动
  2. 分类层级数据:如将组织部门层级数据:“/集团/分公司/信息技术部/数据团队”

除此之外,在一些特定的业务场景中,如证券场景中,需要将一笔回购合约涉及到的多个质押券进行拆分(提取每个质押券有质押数量及对应标准券转换比例),数据示例如下:

image

 另外,API请求的返回的数据多为半结构化的字典列表数据,需要将每行数据从列表中进行提取出来再进行后续的处理,如以下数据:

{"data": [
   {
"AMOUNT":-9000,"SUB_TYPE_NAME":"债券分销","BRANCH_NAME":"银行间","TYPE_NAME":"收入","BUSI_DATE":"20250831","PROJECT_NAME":"调整1月分销佣金-24****MTN001"}, {"AMOUNT":-1075.61,"SUB_TYPE_NAME":"债券分销","BRANCH_NAME":"银行间","TYPE_NAME":"收入","BUSI_DATE":"20250531","PROJECT_NAME":"调整计提1月及3月分销佣金"} ], "success":true }

二,各类主流SQL方言实现方法

针对这类场景,目前没有标准SQL函数支持实现该功能。各类SQL方言通过自定义方法进行支持,以下是常用的实现方法。

Spark/Hive SQL

采用split + explode(及升级版posexplode)。以下为测试案例:

0

 利用该方法可以轻松的回购质押券进行拆分处理:

image

PostgreSQL

有两种方法:

方法一:首先利用string_to_array将字符串切割成数组,然后利用unnest将数组扩展成表

image

方法二:直接利用regexp_split_to_table将字符串切割并转换成表

image

select string_to_array('apple,banana,orange', ',') as item;
select string_to_array('apple|banana|orange', '|') as item;
select unnest(string_to_array('apple,banana,orange', ',')) as item;

select regexp_split_to_array('apple|banana|orange', '\|') as item;
select regexp_split_to_table('apple|banana|orange', '\|') as item;

View Code

Oracle

利用connect by + Level来实现

0

WITH CTE_DATA AS (
    SELECT 'tom' AS NAME, 'apple,banana,cherry' AS FRUIT FROM DUAL
)
SELECT NAME, REGEXP_SUBSTR(FRUIT, '[^,]+', 1, LEVEL) AS FRUIT
FROM CTE_DATA
CONNECT BY REGEXP_SUBSTR(FRUIT, '[^,]+', 1, LEVEL) IS NOT NULL
;

View Code

MySQL

5.x+版本只能使用数字辅助表+SUBSTRING_INDEX。

image

CREATE TABLE IF NOT EXISTS numbers (n INT PRIMARY KEY);
INSERT INTO numbers
SELECT a.N + b.N * 10 + c.N * 100 + 1 AS n
FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a
CROSS JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b
CROSS JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c;
-- 使用数字表分割
SELECT
SUBSTRING_INDEX(
SUBSTRING_INDEX('a,b,c,d', ',', numbers.n),
',',
-1
) AS part
FROM numbers
WHERE numbers.n <= LENGTH('a,b,c,d') - LENGTH(REPLACE('a,b,c,d', ',', '')) + 1;

View Code

8.0+版本可使用json_table

SELECT 
    o.order_id,
    j.product_id
FROM orders o
JOIN JSON_TABLE(
    CONCAT('["', REPLACE(o.product_ids, ',', '","'), '"]'),
    '$[*]' COLUMNS (product_id INT PATH '$')
) AS j;

SQL Server

早期版本无内置函数,只能通过自定义表值函数(TVF)或者XML方法

CREATE FUNCTION dbo.SplitString
(
    @String NVARCHAR(MAX),
    @Delimiter CHAR(1)
)
RETURNS @Results TABLE 
(
    ID INT IDENTITY(1,1),
    Value NVARCHAR(MAX)
)
AS
BEGIN
    DECLARE @pos INT = 0
    DECLARE @slice NVARCHAR(MAX)

    IF RIGHT(@String, 1) != @Delimiter
        SET @String = @String + @Delimiter

    WHILE CHARINDEX(@Delimiter, @String) > 0
    BEGIN
        SET @pos = CHARINDEX(@Delimiter, @String)
        SET @slice = LEFT(@String, @pos - 1)
        
        INSERT INTO @Results (Value) VALUES (@slice)
        SET @String = STUFF(@String, 1, @pos, '')
    END
    
    RETURN
END

-- 使用示例
SELECT * FROM dbo.SplitString('张三,李四,王五', ',')

View Code

DECLARE @str NVARCHAR(100) = '苹果|香蕉|橙子';
DECLARE @separator CHAR(1) = '|';

SELECT 
    LTRIM(RTRIM(m.n.value('.[1]', 'NVARCHAR(100)'))) AS SplitValue
FROM 
    (SELECT CAST('<x>' + REPLACE(@str, @separator, '</x><x>') + '</x>' AS XML)) AS t(x)
CROSS APPLY 
    x.nodes('/x') AS m(n);

View Code

2016之后的版本可使用原生方法STRING_SPLIT

--带序号的版本(SQL Server 2022+)
SELECT value, ordinal
FROM STRING_SPLIT('a,b,c', ',', 1) -- 第三个参数启用序号

三、结论

  Spark SQL、PostgreSQL最方便,思路也比较相似,都是先将字符串拆分数组,然后扩展成表。SQLServer新版本实现较为方法,直接一个函数搞定。Oracle利用其connect by来实现,也相对便捷,只是相对主流SQL方言比较小众一点。Mysql新版本相对方便一点,老版本需要辅助表增加维护成本。

四、参考链接