if not object_id('Tab') is null drop table Tab Go Create table Tab([Col1] int,[Col2] nvarchar(1)) Insert Tab select 1,N'a' union all select 1,N'b' union all select 1,N'c' union all select 2,N'd' union all select 2,N'e' union all select 3,N'f' Go合并表:SQL2000用函数:go if object_id('F_Str') is not null drop function F_Str go create function F_Str(@Col1 int) returns nvarchar(100) as begin declare @S nvarchar(100) select @S=isnull(@S+',','')+Col2 from Tab where Col1=@Col1 return @S end go Select distinct Col1,Col2=dbo.F_Str(Col1) from TabgoSQL2005用XML:方法1:select a.Col1,Col2=stuff(b.Col2.value('/R[1]','nvarchar(max)'),1,1,'') from (select distinct COl1 from Tab) a Cross apply (select COl2=(select N','+Col2 from Tab where Col1=a.COl1 For XML PATH(''), ROOT('R'), TYPE))b方法2:select a.Col1,COl2=replace(b.Col2.value('/Tab[1]','nvarchar(max)'),char(44)+char(32),char(44)) from (select distinct COl1 from Tab) a cross apply (select Col2=(select COl2 from Tab where COl1=a.COl1 FOR XML AUTO, TYPE) .query('<Tab> {for $i in /Tab[position()<last()]/@COl2 return concat(string($i),",")} {concat("",string(/Tab[last()]/@COl2))} </Tab>') )bSQL05用CTE:;with roy as(select Col1,Col2,row=row_number()over(partition by COl1 order by COl1) from Tab) ,Roy2 as (select COl1,cast(COl2 as nvarchar(100))COl2,row from Roy where row=1 union all select a.Col1,cast(b.COl2+','+a.COl2 as nvarchar(100)),a.row from Roy a join Roy2 b on a.COl1=b.COl1 and a.row=b.row+1) select Col1,Col2 from Roy2 a where row=(select max(row) from roy where Col1=a.COl1) order by Col1 option (MAXRECURSION 0) 生成结果: /* Col1 COl2 ----------- ------------ 1 a,b,c 2 d,e 3 f(3 行受影响) */
每组 <=2 条记录的合并 --处理的数据 CREATE TABLE tb(col1 varchar(10),col2 int) INSERT tb SELECT 'a',1 UNION ALL SELECT 'a',2 UNION ALL SELECT 'b',1 UNION ALL SELECT 'b',2 UNION ALL SELECT 'c',3--合并处理 SELECT col1, col2=CAST(MIN(col2) as varchar) +CASE WHEN COUNT(*)=1 THEN '' ELSE ','+CAST(MAX(col2) as varchar) END FROM tb GROUP BY col1 DROP TABLE tb /*--结果 col1 col2 ---------- ---------- a 1,2 b 1,2 c 3 --*/--3.3.4.2 每组 <=3 条记录的合并 --处理的数据 CREATE TABLE tb(col1 varchar(10),col2 int) INSERT tb SELECT 'a',1 UNION ALL SELECT 'a',2 UNION ALL SELECT 'b',1 UNION ALL SELECT 'b',2 UNION ALL SELECT 'b',3 UNION ALL SELECT 'c',3--合并处理 SELECT col1, col2=CAST(MIN(col2) as varchar) +CASE WHEN COUNT(*)=3 THEN ',' +CAST((SELECT col2 FROM tb WHERE col1=a.col1 AND col2 NOT IN(MAX(a.col2),MIN(a.col2))) as varchar) ELSE '' END +CASE WHEN COUNT(*)>=2 THEN ','+CAST(MAX(col2) as varchar) ELSE '' END FROM tb a GROUP BY col1 DROP TABLE tb /*--结果 col1 col2 ---------- ------------ a 1,2 b 1,2,3 c 3 --*/ GO
合并列值 原著:邹建 改编:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-12-16 广东深圳表结构,数据如下: id value ----- ------ 1 aa 1 bb 2 aaa 2 bbb 2 ccc需要得到结果: id values ------ ----------- 1 aa,bb 2 aaa,bbb,ccc 即:group by id, 求 value 的和(字符串相加)1. 旧的解决方法(在sql server 2000中只能用函数解决。) --1. 创建处理函数 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 int) RETURNS varchar(8000) AS BEGIN DECLARE @r varchar(8000) SET @r = '' SELECT @r = @r + ',' + value FROM tb WHERE id=@id RETURN STUFF(@r, 1, 1, '') END GO-- 调用函数 SELECt id, value = dbo.f_str(id) FROM tb GROUP BY iddrop table tb drop function dbo.f_str/* id value ----------- ----------- 1 aa,bb 2 aaa,bbb,ccc (所影响的行数为 2 行) */--2、另外一种函数. 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--创建一个合并的函数 create function f_hb(@id int) returns varchar(8000) as begin declare @str varchar(8000) set @str = '' select @str = @str + ',' + cast(value as varchar) from tb where id = @id set @str = right(@str , len(@str) - 1) return(@str) End go--调用自定义函数得到结果: select distinct id ,dbo.f_hb(id) as value from tbdrop table tb drop function dbo.f_hb/* id value ----------- ----------- 1 aa,bb 2 aaa,bbb,ccc (所影响的行数为 2 行) */2. 新的解决方法(在sql server 2005中用OUTER APPLY等解决。) 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 -- 查询处理 SELECT * FROM(SELECT DISTINCT id FROM tb)A OUTER APPLY( SELECT [values]= STUFF(REPLACE(REPLACE( ( SELECT value FROM tb N WHERE id = A.id FOR XML AUTO ), '<N value="', ','), '"/>', ''), 1, 1, '') )N drop table tb/* id values ----------- ----------- 1 aa,bb 2 aaa,bbb,ccc(2 行受影响) */--SQL2005中的方法2 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, [values]=stuff((select ','+[value] from tb t where id=tb.id for xml path('')), 1, 1, '') from tb group by id/* id values ----------- -------------------- 1 aa,bb 2 aaa,bbb,ccc(2 row(s) affected)*/drop table tb
--sql 2000中使用函数完成.create table tb(id int, data varchar(10)) insert into tb values(1 , 'a') insert into tb values(1 , 'b') insert into tb values(1 , 'c') insert into tb values(2 , 'aa') insert into tb values(2 , 'bb') go--创建一个合并的函数 create function f_hb(@id int) returns varchar(8000) as begin declare @str varchar(8000) set @str = '' select @str = @str + cast(data as varchar) from tb where id = @id set @str = right(@str , len(@str)) return(@str) End go--调用自定义函数得到结果: select distinct id ,dbo.f_hb(id) as data from tbdrop table tb drop function dbo.f_hb/* id data ----------- ------ 1 abc 2 aabb(所影响的行数为 2 行) */
create table tb(id int, data varchar(10)) insert into tb values(1 , 'a') insert into tb values(1 , 'b') insert into tb values(1 , 'c') insert into tb values(2 , 'aa') insert into tb values(2 , 'bb') goselect id, [data]=replace((select ','+[data] from tb t where id=tb.id for xml path('')),',','') from tb group by iddrop table tb/* id data ----------- ---- 1 abc 2 aabb(2 行受影响) */
乌龟,为什么要套一层呢,这样不是很好么? create table tb(id int, data varchar(10)) insert into tb values(1 , 'a') insert into tb values(1 , 'b') insert into tb values(1 , 'c') insert into tb values(2 , 'aa') insert into tb values(2 , 'bb') goselect id, [data]=(select ''+[data] from tb t where id=tb.id for xml path('')) from tb group by iddrop table tb 呵呵
if object_id('test') is not null drop table test go create table test(id int,data varchar(10)) insert into test select 1,'a' union select 1,'b' union select 1,'c' union select 2,'aa' union select 2,'bb ' gocreate function get(@id int) returns varchar(20) as begin declare @sql vARchar(100) select @sql=isnull(@sql,'')+data from test where id=@id return @sqlend go select id,dbo.get(id) from test group by id--------------------- id ----------- -------------------- 1 abc 2 aabb (所影响的行数为 2 行)
--> --> (Andy)生成测试数据 2008-10-29 Set Nocount On declare @1 table([id] int,[data] nvarchar(2)) Insert @1 select 1,N'a' union all select 1,N'b' union all select 1,N'c' union all select 2,N'aa' union all select 2,N'bb'--1 ;With t1 As (Select r=Row_number() Over(Partition By id Order By data),id,data From @1) ,t2 As ( Select r,id,data,x=Convert(nvarchar(200),data) From t1 Where r=1 Union All Select b.r,b.id,b.data ,x=Convert(nvarchar(200),a.x+b.data) From t2 As a Inner Join t1 As b On b.id=a.id And b.r=a.r+1 ) Select id,Max(x) As data From t2 Group By id--2 Select * From (Select Distinct id From @1) As a Outer Apply(Select data=(Select ''+data From @1 Where id=a.id For Xml Path(''))) As b/* id data ----------------- 1 abc 2 aabb */
2005可以实现--合并分拆表
/******************************************************************************************************************************************************
合并分拆表数据整理人:中国风(Roy)日期:2008.06.06
******************************************************************************************************************************************************/--> --> (Roy)生成測試數據
if not object_id('Tab') is null
drop table Tab
Go
Create table Tab([Col1] int,[Col2] nvarchar(1))
Insert Tab
select 1,N'a' union all
select 1,N'b' union all
select 1,N'c' union all
select 2,N'd' union all
select 2,N'e' union all
select 3,N'f'
Go合并表:SQL2000用函数:go
if object_id('F_Str') is not null
drop function F_Str
go
create function F_Str(@Col1 int)
returns nvarchar(100)
as
begin
declare @S nvarchar(100)
select @S=isnull(@S+',','')+Col2 from Tab where Col1=@Col1
return @S
end
go
Select distinct Col1,Col2=dbo.F_Str(Col1) from TabgoSQL2005用XML:方法1:select
a.Col1,Col2=stuff(b.Col2.value('/R[1]','nvarchar(max)'),1,1,'')
from
(select distinct COl1 from Tab) a
Cross apply
(select COl2=(select N','+Col2 from Tab where Col1=a.COl1 For XML PATH(''), ROOT('R'), TYPE))b方法2:select
a.Col1,COl2=replace(b.Col2.value('/Tab[1]','nvarchar(max)'),char(44)+char(32),char(44))
from
(select distinct COl1 from Tab) a
cross apply
(select Col2=(select COl2 from Tab where COl1=a.COl1 FOR XML AUTO, TYPE)
.query('<Tab>
{for $i in /Tab[position()<last()]/@COl2 return concat(string($i),",")}
{concat("",string(/Tab[last()]/@COl2))}
</Tab>')
)bSQL05用CTE:;with roy as(select Col1,Col2,row=row_number()over(partition by COl1 order by COl1) from Tab)
,Roy2 as
(select COl1,cast(COl2 as nvarchar(100))COl2,row from Roy where row=1
union all
select a.Col1,cast(b.COl2+','+a.COl2 as nvarchar(100)),a.row from Roy a join Roy2 b on a.COl1=b.COl1 and a.row=b.row+1)
select Col1,Col2 from Roy2 a where row=(select max(row) from roy where Col1=a.COl1) order by Col1 option (MAXRECURSION 0)
生成结果:
/*
Col1 COl2
----------- ------------
1 a,b,c
2 d,e
3 f(3 行受影响)
*/
每组 <=2 条记录的合并
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'c',3--合并处理
SELECT col1,
col2=CAST(MIN(col2) as varchar)
+CASE
WHEN COUNT(*)=1 THEN ''
ELSE ','+CAST(MAX(col2) as varchar)
END
FROM tb
GROUP BY col1
DROP TABLE tb
/*--结果
col1 col2
---------- ----------
a 1,2
b 1,2
c 3
--*/--3.3.4.2 每组 <=3 条记录的合并
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3
UNION ALL SELECT 'c',3--合并处理
SELECT col1,
col2=CAST(MIN(col2) as varchar)
+CASE
WHEN COUNT(*)=3 THEN ','
+CAST((SELECT col2 FROM tb WHERE col1=a.col1 AND col2 NOT IN(MAX(a.col2),MIN(a.col2))) as varchar)
ELSE ''
END
+CASE
WHEN COUNT(*)>=2 THEN ','+CAST(MAX(col2) as varchar)
ELSE ''
END
FROM tb a
GROUP BY col1
DROP TABLE tb
/*--结果
col1 col2
---------- ------------
a 1,2
b 1,2,3
c 3
--*/
GO
原著:邹建
改编:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-12-16 广东深圳表结构,数据如下:
id value
----- ------
1 aa
1 bb
2 aaa
2 bbb
2 ccc需要得到结果:
id values
------ -----------
1 aa,bb
2 aaa,bbb,ccc
即:group by id, 求 value 的和(字符串相加)1. 旧的解决方法(在sql server 2000中只能用函数解决。)
--1. 创建处理函数
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 int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + ',' + value FROM tb WHERE id=@id
RETURN STUFF(@r, 1, 1, '')
END
GO-- 调用函数
SELECt id, value = dbo.f_str(id) FROM tb GROUP BY iddrop table tb
drop function dbo.f_str/*
id value
----------- -----------
1 aa,bb
2 aaa,bbb,ccc
(所影响的行数为 2 行)
*/--2、另外一种函数.
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--创建一个合并的函数
create function f_hb(@id int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' + cast(value as varchar) from tb where id = @id
set @str = right(@str , len(@str) - 1)
return(@str)
End
go--调用自定义函数得到结果:
select distinct id ,dbo.f_hb(id) as value from tbdrop table tb
drop function dbo.f_hb/*
id value
----------- -----------
1 aa,bb
2 aaa,bbb,ccc
(所影响的行数为 2 行)
*/2. 新的解决方法(在sql server 2005中用OUTER APPLY等解决。)
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
-- 查询处理
SELECT * FROM(SELECT DISTINCT id FROM tb)A OUTER APPLY(
SELECT [values]= STUFF(REPLACE(REPLACE(
(
SELECT value FROM tb N
WHERE id = A.id
FOR XML AUTO
), '<N value="', ','), '"/>', ''), 1, 1, '')
)N
drop table tb/*
id values
----------- -----------
1 aa,bb
2 aaa,bbb,ccc(2 行受影响)
*/--SQL2005中的方法2
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, [values]=stuff((select ','+[value] from tb t where id=tb.id for xml path('')), 1, 1, '')
from tb
group by id/*
id values
----------- --------------------
1 aa,bb
2 aaa,bbb,ccc(2 row(s) affected)*/drop table tb
insert into tb values(1 , 'a')
insert into tb values(1 , 'b')
insert into tb values(1 , 'c')
insert into tb values(2 , 'aa')
insert into tb values(2 , 'bb')
go--创建一个合并的函数
create function f_hb(@id int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + cast(data as varchar) from tb where id = @id
set @str = right(@str , len(@str))
return(@str)
End
go--调用自定义函数得到结果:
select distinct id ,dbo.f_hb(id) as data from tbdrop table tb
drop function dbo.f_hb/*
id data
----------- ------
1 abc
2 aabb(所影响的行数为 2 行)
*/
insert into tb values(1 , 'a')
insert into tb values(1 , 'b')
insert into tb values(1 , 'c')
insert into tb values(2 , 'aa')
insert into tb values(2 , 'bb')
goselect id, [data]=replace((select ','+[data] from tb t where id=tb.id for xml path('')),',','')
from tb
group by iddrop table tb/*
id data
----------- ----
1 abc
2 aabb(2 行受影响)
*/
create table tb(id int, data varchar(10))
insert into tb values(1 , 'a')
insert into tb values(1 , 'b')
insert into tb values(1 , 'c')
insert into tb values(2 , 'aa')
insert into tb values(2 , 'bb')
goselect id, [data]=(select ''+[data] from tb t where id=tb.id for xml path(''))
from tb
group by iddrop table tb
呵呵
drop table test
go
create table test(id int,data varchar(10))
insert into test select 1,'a' union
select 1,'b' union
select 1,'c' union
select 2,'aa' union
select 2,'bb '
gocreate function get(@id int)
returns varchar(20)
as
begin
declare @sql vARchar(100)
select @sql=isnull(@sql,'')+data
from test
where id=@id
return @sqlend
go
select id,dbo.get(id)
from test
group by id---------------------
id
----------- --------------------
1 abc
2 aabb (所影响的行数为 2 行)
Set Nocount On
declare @1 table([id] int,[data] nvarchar(2))
Insert @1
select 1,N'a' union all
select 1,N'b' union all
select 1,N'c' union all
select 2,N'aa' union all
select 2,N'bb'--1
;With t1 As
(Select r=Row_number() Over(Partition By id Order By data),id,data From @1)
,t2 As
(
Select r,id,data,x=Convert(nvarchar(200),data) From t1 Where r=1
Union All
Select b.r,b.id,b.data ,x=Convert(nvarchar(200),a.x+b.data)
From t2 As a
Inner Join t1 As b On b.id=a.id And b.r=a.r+1
)
Select id,Max(x) As data From t2 Group By id--2
Select * From (Select Distinct id From @1) As a
Outer Apply(Select data=(Select ''+data From @1 Where id=a.id For Xml Path(''))) As b/*
id data
-----------------
1 abc
2 aabb
*/