CREATE TABLE [#tb] ( [id] int , [name] varchar(30) ) GO--插入测试数据 INSERT INTO [#tb] ([id],[name]) SELECT '1','a' UNION SELECT '2','b' UNION SELECT '3','c' UNION SELECT '4','c,d,e' UNION SELECT '5','e,f,g,h,i' GO SELECT * FROM [#tb]SELECT A.id, B.NAME FROM( SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE(NAME, ',', '</v><v>') + '</v></root>') FROM #tb )A OUTER APPLY( SELECT NAME = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v) )Bid NAME ----------- ------------------------------- 1 a 2 b 3 c 4 c 4 d 4 e 5 e 5 f 5 g 5 h 5 i(11 row(s) affected)
大侠请注释,不太明白 SELECT A.id, B.NAME FROM( SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE(NAME, ',', '</v><v>') + '</v></root>') FROM #tb )A OUTER APPLY( SELECT NAME = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v) )B
/* 标题:按某字段合并字符串之一(简单合并) 作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 时间:2008-11-06 地点:广东深圳描述:将如下形式的数据按id字段合并value字段。 id value ----- ------ 1 aa 1 bb 2 aaa 2 bbb 2 ccc 需要得到结果: id value ------ ----------- 1 aa,bb 2 aaa,bbb,ccc 即:group by id, 求 value 的和(字符串相加) */ --1、sql2000中只能用自定义的函数解决 create table tb(id int, value varchar(10)) insert into tb values(1, 'aa') insert into tb values(1, 'bb') insert into tb values(2, 'aaa') insert into tb values(2, 'bbb') insert into tb values(2, 'ccc') gocreate function dbo.f_str(@id varchar(10)) returns varchar(1000) as begin declare @str varchar(1000) select @str = isnull(@str + ',' , '') + cast(value as varchar) from tb where id = @id return @str end go--调用函数 select id , value = dbo.f_str(id) from tb group by iddrop function dbo.f_str drop table tb --2、sql2005中的方法 create table tb(id int, value varchar(10)) insert into tb values(1, 'aa') insert into tb values(1, 'bb') insert into tb values(2, 'aaa') insert into tb values(2, 'bbb') insert into tb values(2, 'ccc') goselect id, [value] = stuff((select ',' + [value] from tb t where id = tb.id for xml path('')) , 1 , 1 , '') from tb group by iddrop table tb --3、使用游标合并数据 create table tb(id int, value varchar(10)) insert into tb values(1, 'aa') insert into tb values(1, 'bb') insert into tb values(2, 'aaa') insert into tb values(2, 'bbb') insert into tb values(2, 'ccc') go declare @t table(id int,value varchar(100))--定义结果集表变量 --定义游标并进行合并处理 declare my_cursor cursor local for select id , value from tb declare @id_old int , @id int , @value varchar(10) , @s varchar(100) open my_cursor fetch my_cursor into @id , @value select @id_old = @id , @s='' while @@FETCH_STATUS = 0 begin if @id = @id_old select @s = @s + ',' + cast(@value as varchar) else begin insert @t values(@id_old , stuff(@s,1,1,'')) select @s = ',' + cast(@value as varchar) , @id_old = @id end fetch my_cursor into @id , @value END insert @t values(@id_old , stuff(@s,1,1,'')) close my_cursor deallocate my_cursorselect * from @t drop table tb
发错了.是这个./* 标题:简单数据拆分(version 2.0) 作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 时间:2010-05-07 地点:重庆航天职业学院 描述:有表tb, 如下: id value ----------- ----------- 1 aa,bb 2 aaa,bbb,ccc 欲按id,分拆value列, 分拆后结果如下: id value ----------- -------- 1 aa 1 bb 2 aaa 2 bbb 2 ccc */--1. 旧的解决方法(sql server 2000)create table tb(id int,value varchar(30)) insert into tb values(1,'aa,bb') insert into tb values(2,'aaa,bbb,ccc') go--方法1.使用临时表完成 SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id) FROM tb A, # B WHERE SUBSTRING(',' + A.[value], B.id, 1) = ','DROP TABLE #--方法2.如果数据量小,可不使用临时表 select a.id , value = substring(a.value , b.number , charindex(',' , a.value + ',' , b.number) - b.number) from tb a join master..spt_values b on b.type='p' and b.number between 1 and len(a.value) where substring(',' + a.value , b.number , 1) = ','--2. 新的解决方法(sql server 2005) create table tb(id int,value varchar(30)) insert into tb values(1,'aa,bb') insert into tb values(2,'aaa,bbb,ccc') go--方法1.使用xml完成 SELECT A.id, B.value FROM ( SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE([value], ',', '</v><v>') + '</v></root>') FROM tb ) A OUTER APPLY ( SELECT value = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v) ) B--方法2.使用CTE完成 ;with tt as (select id,[value]=cast(left([value],charindex(',',[value]+',')-1) as nvarchar(100)),Split=cast(stuff([value]+',',1,charindex(',',[value]+','),'') as nvarchar(100)) from tb union all select id,[value]=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from tt where split>'' ) select id,[value] from tt order by id option (MAXRECURSION 0) DROP TABLE tb/* id value ----------- ------------------------------ 1 aa 1 bb 2 aaa 2 bbb 2 ccc(5 行受影响) */
(
[id] int ,
[name] varchar(30)
)
GO--插入测试数据
INSERT INTO [#tb] ([id],[name])
SELECT '1','a' UNION
SELECT '2','b' UNION
SELECT '3','c' UNION
SELECT '4','c,d,e' UNION
SELECT '5','e,f,g,h,i'
GO
SELECT * FROM [#tb]SELECT A.id, B.NAME
FROM(
SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE(NAME, ',', '</v><v>') + '</v></root>') FROM #tb
)A
OUTER APPLY(
SELECT NAME = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v)
)Bid NAME
----------- -------------------------------
1 a
2 b
3 c
4 c
4 d
4 e
5 e
5 f
5 g
5 h
5 i(11 row(s) affected)
SELECT A.id, B.NAME
FROM(
SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE(NAME, ',', '</v><v>') + '</v></root>') FROM #tb
)A
OUTER APPLY(
SELECT NAME = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v)
)B
标题:按某字段合并字符串之一(简单合并)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-11-06
地点:广东深圳描述:将如下形式的数据按id字段合并value字段。
id value
----- ------
1 aa
1 bb
2 aaa
2 bbb
2 ccc
需要得到结果:
id value
------ -----------
1 aa,bb
2 aaa,bbb,ccc
即:group by id, 求 value 的和(字符串相加)
*/
--1、sql2000中只能用自定义的函数解决
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
gocreate function dbo.f_str(@id varchar(10)) returns varchar(1000)
as
begin
declare @str varchar(1000)
select @str = isnull(@str + ',' , '') + cast(value as varchar) from tb where id = @id
return @str
end
go--调用函数
select id , value = dbo.f_str(id) from tb group by iddrop function dbo.f_str
drop table tb
--2、sql2005中的方法
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
goselect id, [value] = stuff((select ',' + [value] from tb t where id = tb.id for xml path('')) , 1 , 1 , '')
from tb
group by iddrop table tb
--3、使用游标合并数据
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go
declare @t table(id int,value varchar(100))--定义结果集表变量
--定义游标并进行合并处理
declare my_cursor cursor local for
select id , value from tb
declare @id_old int , @id int , @value varchar(10) , @s varchar(100)
open my_cursor
fetch my_cursor into @id , @value
select @id_old = @id , @s=''
while @@FETCH_STATUS = 0
begin
if @id = @id_old
select @s = @s + ',' + cast(@value as varchar)
else
begin
insert @t values(@id_old , stuff(@s,1,1,''))
select @s = ',' + cast(@value as varchar) , @id_old = @id
end
fetch my_cursor into @id , @value
END
insert @t values(@id_old , stuff(@s,1,1,''))
close my_cursor
deallocate my_cursorselect * from @t
drop table tb
标题:简单数据拆分(version 2.0)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2010-05-07
地点:重庆航天职业学院
描述:有表tb, 如下:
id value
----------- -----------
1 aa,bb
2 aaa,bbb,ccc
欲按id,分拆value列, 分拆后结果如下:
id value
----------- --------
1 aa
1 bb
2 aaa
2 bbb
2 ccc
*/--1. 旧的解决方法(sql server 2000)create table tb(id int,value varchar(30))
insert into tb values(1,'aa,bb')
insert into tb values(2,'aaa,bbb,ccc')
go--方法1.使用临时表完成
SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)
FROM tb A, # B
WHERE SUBSTRING(',' + A.[value], B.id, 1) = ','DROP TABLE #--方法2.如果数据量小,可不使用临时表
select a.id , value = substring(a.value , b.number , charindex(',' , a.value + ',' , b.number) - b.number)
from tb a join master..spt_values b
on b.type='p' and b.number between 1 and len(a.value)
where substring(',' + a.value , b.number , 1) = ','--2. 新的解决方法(sql server 2005)
create table tb(id int,value varchar(30))
insert into tb values(1,'aa,bb')
insert into tb values(2,'aaa,bbb,ccc')
go--方法1.使用xml完成
SELECT A.id, B.value FROM
(
SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE([value], ',', '</v><v>') + '</v></root>') FROM tb
) A OUTER APPLY
(
SELECT value = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v)
) B--方法2.使用CTE完成
;with tt as
(select id,[value]=cast(left([value],charindex(',',[value]+',')-1) as nvarchar(100)),Split=cast(stuff([value]+',',1,charindex(',',[value]+','),'') as nvarchar(100)) from tb
union all
select id,[value]=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from tt where split>''
)
select id,[value] from tt order by id option (MAXRECURSION 0)
DROP TABLE tb/*
id value
----------- ------------------------------
1 aa
1 bb
2 aaa
2 bbb
2 ccc(5 行受影响)
*/