如何把字段中用逗号隔开的一条数据分开成多条数据

qq_21880229 2017-09-21 10:53:30

我想要的是
tableA
id group_id
1 a
2 a,b
3 a,b,c

id group_id
1 a
2 a
2 b
3 a
3 b
3 c
网上找了许多方法,能执行语句,但是查询出来的结果不全
...全文
3360 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
多一点热爱 2019-07-03
  • 打赏
  • 举报
回复
--参考
拆分表:

--> --> (Roy)生成測試數據

if not object_id('Tab') is null
drop table Tab
Go
Create table Tab([Col1] int,[COl2] nvarchar(5))
Insert Tab
select 1,N'a,b,c' union all
select 2,N'd,e' union all
select 3,N'f'
Go

SQL2000用辅助表:
if object_id('Tempdb..#Num') is not null
drop table #Num
go
select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b
Select
a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID)
from
Tab a,#Num b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','


SQL2005用Xml:

select
a.COl1,b.Col2
from
(select Col1,COl2=convert(xml,' <root> <v>'+replace(COl2,',',' </v> <v>')+' </v> </root>') from Tab)a
outer apply
(select Col2=C.v.value('.','nvarchar(100)') from a.COl2.nodes('/root/v')C(v))b


SQL05用CTE:

;with roy as
(select Col1,COl2=cast(left(Col2,charindex(',',Col2+',')-1) as nvarchar(100)),Split=cast(stuff(COl2+',',1,charindex(',',Col2+','),'') as nvarchar(100)) from Tab
union all
select Col1,COl2=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from Roy where split>''
)
select COl1,COl2 from roy order by COl1 option (MAXRECURSION 0)

生成结果:
/*
Col1 COl2
----------- -----
a
b
c
d
e
f
*/
繁花尽流年 2017-09-21
  • 打赏
  • 举报
回复
引用 3 楼 foren_whb 的回复:
呵呵,都是不懂范式理论,滥建表滥用表的结果。。。。。 这个表,明显是多对多mapping表,搞成这样。。。
没这么极端,很多时候当用第三方提供的数据时,就会出现这种鬼数据。
丰云 2017-09-21
  • 打赏
  • 举报
回复
呵呵,都是不懂范式理论,滥建表滥用表的结果。。。。。 这个表,明显是多对多mapping表,搞成这样。。。
繁花尽流年 2017-09-21
  • 打赏
  • 举报
回复
IF NOT OBJECT_ID(N'Tempdb..#T') IS NULL DROP TABLE #T
GO
CREATE TABLE #T([id] INT, [type] NVARCHAR(23), [value] NVARCHAR(30))
INSERT #T
SELECT 1, N'类型1', N'aa,bb' UNION ALL
SELECT 2, N'类型2', N'aaa,bbb,ccc' UNION ALL
SELECT 3, N'类型3', N'aaa,bbb,ddd'
GO

SELECT a.id,a.[type],SUBSTRING(a.[value], b.number, CHARINDEX(',', a.[value]+',', b.number)-b.number) AS [value]
FROM   #T a
       JOIN MASTER.dbo.spt_values b
            ON CHARINDEX(',', ','+a.[value], b.number) = b.number
WHERE  b.[type]= 'P'

id          type                    value
----------- ----------------------- ------------------------------
1           类型1                     aa
2           类型2                     aaa
3           类型3                     aaa
1           类型1                     bb
2           类型2                     bbb
3           类型3                     bbb
2           类型2                     ccc
3           类型3                     ddd
参考下
acen_chen 2017-09-21
  • 打赏
  • 举报
回复
未必,有时只能这样,看应用场景
二月十六 2017-09-21
  • 打赏
  • 举报
回复
新建函数:
CREATE FUNCTION dbo.f_splitstr(@SourceSql   NVARCHAR(MAX),@StrSeprate   VARCHAR(100))   
RETURNS @temp TABLE(F1 VARCHAR(100))
AS
BEGIN
DECLARE @ch AS VARCHAR(100)
SET @SourceSql=@SourceSql+@StrSeprate
WHILE(@SourceSql<>'')
BEGIN
SET @ch=LEFT(@SourceSql,CHARINDEX(@StrSeprate,@SourceSql,1)-1)
INSERT @temp VALUES(@ch)
SET @SourceSql=STUFF(@SourceSql,1,CHARINDEX(@StrSeprate,@SourceSql,1),'')
END
RETURN
END
GO


查询语句:
--测试数据
if not object_id(N'Tempdb..#Tablea') is null
drop table #Tablea
Go
Create table #Tablea([id] int,[group_id] nvarchar(25))
Insert #Tablea
select 1,N'a' union all
select 2,N'a,b' union all
select 3,N'a,d,c'
Go
--测试数据结束
SELECT id ,
f1 AS group_id
FROM #Tablea
CROSS APPLY ( SELECT *
FROM dbo.f_splitstr(group_id, ',')
) t


结果:

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧