SQL Server:将产品表中逗号分隔状态码替换为状态描述
解决方案:将逗号分隔状态码替换为对应描述
这是个很常见的字符串拆分关联场景,在SQL Server里用内置函数就能轻松搞定,我给你一步步拆解实现过程:
1. 先确认示例表结构与测试数据
首先把你的示例数据转换成可执行的SQL,方便快速验证:
-- 创建并填充Products表 CREATE TABLE Products ( Name VARCHAR(50), [Status Code] VARCHAR(100) ); INSERT INTO Products VALUES ('Product 1', '1001, 1003'), ('Product 2', '1001, 1005, 1006'); -- 创建并填充Status表 CREATE TABLE Status ( Code VARCHAR(10), Description VARCHAR(50) ); INSERT INTO Status VALUES ('1001', 'State A'), ('1003', 'State B'), ('1005', 'State C'), ('1006', 'State D');
2. 核心实现SQL
用STRING_SPLIT拆分逗号分隔的状态码,关联Status表获取描述,再用STRING_AGG合并回逗号分隔的字符串:
SELECT p.Name, STRING_AGG(s.Description, ', ') AS StatusDescriptions FROM Products p -- 把每个产品的状态码拆分成单独行 CROSS APPLY STRING_SPLIT(p.[Status Code], ',') AS split -- 关联状态表,注意去掉拆分后值的前后空格(原数据里有空格分隔) JOIN Status s ON LTRIM(RTRIM(split.value)) = s.Code -- 按产品名称分组,合并对应的状态描述 GROUP BY p.Name ORDER BY p.Name;
执行后就能得到你想要的结果:
| Name | StatusDescriptions |
|---|---|
| Product 1 | State A, State B |
| Product 2 | State A, State C, State D |
3. 扩展处理:兼容不存在的状态码
如果Products表里存在Status表中没有的状态码,你可以用LEFT JOIN替代JOIN,并通过ISNULL标记未知状态:
SELECT p.Name, STRING_AGG( ISNULL(s.Description, 'Unknown: ' + LTRIM(RTRIM(split.value))), ', ' ) AS StatusDescriptions FROM Products p CROSS APPLY STRING_SPLIT(p.[Status Code], ',') AS split LEFT JOIN Status s ON LTRIM(RTRIM(split.value)) = s.Code GROUP BY p.Name ORDER BY p.Name;
低版本SQL Server兼容方案
如果你的SQL Server版本低于2017(不支持STRING_AGG),可以用FOR XML PATH的方式来合并字符串:
SELECT p.Name, STUFF(( SELECT ', ' + s.Description FROM STRING_SPLIT(p.[Status Code], ',') AS split JOIN Status s ON LTRIM(RTRIM(split.value)) = s.Code FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(MAX)'), 1, 2, '') AS StatusDescriptions FROM Products p GROUP BY p.Name ORDER BY p.Name;
内容的提问来源于stack exchange,提问作者Lucian
相关产品推荐
相关产品推荐

