怎么一行拆分成多行?

qq_38446992 2017-08-22 10:59:52
原始数据如下:
id tpye value
1 类型1 aa,bb
2 类型2 aaa,bbb,ccc
3 类型3 aaa,bbb,ddd


想得到的结果如下:
id tpye value
1 类型1 aa
1 类型1 bb
2 类型2 aaa
2 类型2 bbb
2 类型2 ccc
3 类型3 aaa
3 类型3 bbb
3 类型3 ddd

哪位大神能帮忙看下怎么写sql,非常感谢,数据库用的是2005。
...全文
842 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
道素 2017-08-23
  • 打赏
  • 举报
回复
字符串分割的方法就行,楼上都说了,我再举个另外实现方法的例子:

;with t(id,tpye,value) AS(
   select 0,N'类型0','aa' union all
   select 1,N'类型1','aa,bb' union all
   select 2,N'类型2','aaa,bbb,ccc'  union all
   select 3,N'类型3','aaa,bbb,ddd'
)
select t.*
      ,substring(t.value,sv.number+1,
           case when 
             charindex(',',t.value,sv.number+1)-sv.number<1 then 
              len(t.value) 
           else charindex(',',t.value,sv.number+1)-sv.number-1 end) 
from t
inner join master.dbo.spt_values as sv on sv.type='P' --and sv.number between 0 and len(value) 
and (substring(t.value,sv.number,1)=','  or sv.number in (0))
order by id
 

+----+------+-------------+-----+
| id | tpye | value       |     |
+----+------+-------------+-----+
| 0  | 类型0  | aa          | aa  |
| 1  | 类型1  | aa,bb       | aa  |
| 1  | 类型1  | aa,bb       | bb  |
| 2  | 类型2  | aaa,bbb,ccc | aaa |
| 2  | 类型2  | aaa,bbb,ccc | bbb |
| 2  | 类型2  | aaa,bbb,ccc | ccc |
| 3  | 类型3  | aaa,bbb,ddd | aaa |
| 3  | 类型3  | aaa,bbb,ddd | bbb |
| 3  | 类型3  | aaa,bbb,ddd | ddd |
+----+------+-------------+-----+
  • 打赏
  • 举报
回复
用 wtih union all递归的方式提取,用stuff把提取的替换为空 这样
  • 打赏
  • 举报
回复

CREATE function [dbo].[fn_splitString](@str nvarchar(50),@char nvarchar(2))
returns @table table(column_str nvarchar(20))
as
begin
declare @index int,@str_sub nvarchar(50)
set @index = charindex(@char,@str)
while @index > 0
begin
set @str_sub = SUBSTRING(@str,1,@index-1)
insert into @table select @str_sub
set @str = SUBSTRING(@str,@index+1,LEN(@str)-charindex(@char,@str))
set @index = charindex(@char,@str)
end
insert into @table select @str
return
end


;WITH step01 AS (
SELECT 1 id ,'类型1' tpye,'aa,bb' value
UNION ALL
SELECT 2 id ,'类型2' tpye,'aaa,bbb,ccc' value
UNION ALL
SELECT 3 id ,'类型3' tpye,'aaa,bbb,ddd' value )

select * from step01 CROSS APPLY dbo.fn_splitString(step01.value,',') a




二月十六 版主 2017-08-22
  • 打赏
  • 举报
回复
CREATE FUNCTION dbo.F_Split
(
@SplitString nvarchar(max), --源字符串
@Separator nvarchar(10)=' ' --分隔符号,默认为空格
)
RETURNS @SplitStringsTable TABLE --输出的数据表
(
[id] int identity(1,1),
[value] nvarchar(max)
)
AS
BEGIN
DECLARE @CurrentIndex int;
DECLARE @NextIndex int;
DECLARE @ReturnText nvarchar(max);

SELECT @CurrentIndex=1;
WHILE(@CurrentIndex<=len(@SplitString))
BEGIN
SELECT @NextIndex=charindex(@Separator,@SplitString,@CurrentIndex);
IF(@NextIndex=0 OR @NextIndex IS NULL)
SELECT @NextIndex=len(@SplitString)+1;
SELECT @ReturnText=substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex);
INSERT INTO @SplitStringsTable([value]) VALUES(@ReturnText);
SELECT @CurrentIndex=@NextIndex+1;
END
RETURN;
END
GO

--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([id] int,[tpye] nvarchar(23),[value] nvarchar(31))
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 id ,
tpye ,
t.value
FROM #T
CROSS APPLY ( SELECT value
FROM dbo.F_Split(value, ',')
) t

吉普赛的歌 版主 2017-08-22
  • 打赏
  • 举报
回复
USE [tempdb]
GO
IF OBJECT_ID('dbo.t') IS NOT NULL DROP TABLE dbo.t
GO
CREATE TABLE [dbo].[t](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[type] [nvarchar](max) NULL,
	[value] NVARCHAR(MAX) NULL
	PRIMARY KEY CLUSTERED 
	(
		[id] ASC
	)
)
INSERT INTO t([type],[value]) VALUES(N'类型1','aa,bb')
INSERT INTO t([type],[value]) VALUES(N'类型2','aaa,bbb,ccc')
INSERT INTO t([type],[value]) VALUES(N'类型3','aaa,bbb,ddd')
GO
IF OBJECT_ID('[dbo].[Fun_Split]') IS NOT NULL
DROP FUNCTION [dbo].[Fun_Split]
GO
-- =============================================
-- Author     :	yenange
-- Create date: 2014-03-04
-- Description:	切分字符串
-- Example    : SELECT * FROM [dbo].[Fun_Split]('a,b,d,c',',')
-- =============================================
CREATE FUNCTION [dbo].[Fun_Split]  
(  
    @str    NVARCHAR(MAX),  
    @separator  NVARCHAR(MAX)  
)
RETURNS TABLE 
AS
RETURN
(
	SELECT ROW_NUMBER() OVER (order by (select 0)) AS rowNum, B.id  
	FROM   (
			SELECT [value] = CONVERT(XML, '<v>' + REPLACE(@str, @separator, '</v><v>') + '</v>')  
		   ) A  
		   OUTER APPLY(  
		SELECT id = N.v.value('.', 'nvarchar(max)')  
		FROM   A.[value].nodes('/v') N(v)  
	) B
	WHERE ISNULL(B.id,'')!=''
)
GO
SELECT t.id,t.[type],fs.[id] AS [value] 
FROM dbo.t CROSS APPLY dbo.Fun_Split(t.[value],',') AS fs
/*
id	type	value
1	类型1	aa
1	类型1	bb
2	类型2	aaa
2	类型2	bbb
2	类型2	ccc
3	类型3	aaa
3	类型3	bbb
3	类型3	ddd
*/
prevail 2017-08-22
  • 打赏
  • 举报
回复
value没有规律 基本上无解
RINK_1 2017-08-22
  • 打赏
  • 举报
回复
SELECT A.ID,A.TYPE, SUBSTRING(VALUE,NUMBER,CHARINDEX(',',VALUE+',',NUMBER)-NUMBER) AS VALUE FROM 表 A JOIN MASTER.DBO.SPT_VALUES B ON CHARINDEX(',',','+VALUE,NUMBER)=NUMBER WHERE B.TYPE='P'

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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