首页 > 解决方案 > 将逗号值分隔为单个值

问题描述

我需要在 SQL Server 中分隔列

表:列分隔

CREATE TABLE [dbo].[columnsseparates](
    [id] [varchar](50) NULL,
    [name] [varchar](500) NULL
) 
INSERT [dbo].[columnsseparates] ([id], [name]) VALUES (N'1,2,3,4', N'abc,xyz,mn')
GO
INSERT [dbo].[columnsseparates] ([id], [name]) VALUES (N'4,5,6', N'xy,yz')
GO
INSERT [dbo].[columnsseparates] ([id], [name]) VALUES (N'7,100', N'yy')
INSERT [dbo].[columnsseparates] ([id], [name]) VALUES (N'101', N'oo,yy')

GO

基于上述数据,我希望输出如下:

id   |  Name 
1    |abc
2    |xyz
3    |mn
4    |null
4    |xy
5    |yz
6    |null
7    |yy
100  |null
101  |oo
null |yy

如何在 SQL Server 中实现此任务?

标签: sql-serversql-server-2012

解决方案


在列中存储非原子值表明模式应该被规范化。


使用PARSENAME(最多 4 个逗号分隔值)的简单方法:

SELECT DISTINCT s.id, s.name
FROM [dbo].[columnsseparates]
CROSS APPLY(SELECT REVERSE(REPLACE(id,',','.')) id,REVERSE(REPLACE(name, ',','.')) name) sub
CROSS APPLY(VALUES (REVERSE(PARSENAME(sub.id,1)), REVERSE(PARSENAME(sub.name,1))),
                   (REVERSE(PARSENAME(sub.id,2)), REVERSE(PARSENAME(sub.name,2))),
                   (REVERSE(PARSENAME(sub.id,3)), REVERSE(PARSENAME(sub.name,3))),
                   (REVERSE(PARSENAME(sub.id,4)), REVERSE(PARSENAME(sub.name,4))) 
         ) AS s(id, name)
ORDER BY s.id;

db<>小提琴演示

输出:

+------+------+
| id   | name |
+------+------+
|      |      |
|      | yy   |
|   1  | abc  |
| 100  |      |
| 101  | oo   |
|   2  | xyz  |
|   3  | mn   |
|   4  |      |
|   4  | xy   |
|   5  | yz   |
|   6  |      |
|   7  | yy   |
+------+------+

推荐阅读