一、问题
有表如下:
如何获得如下结果:
二、解法一
使用xml转换
代码如下:
01 |
CREATE TABLE body |
02 |
( |
03 |
ID int , |
04 |
BODY nvarchar(20) |
05 |
) |
06 |
go |
07 |
INSERT INTO body VALUES (1, 'aaaa' ) |
08 |
INSERT INTO body VALUES (2, 'bbbb' ) |
09 |
INSERT INTO body VALUES (1, 'cccccc' ) |
10 |
INSERT INTO body VALUES (3, 'ddddd' ) |
11 |
go |
12 |
SELECT * FROM body |
13 |
|
14 |
SELECT distinct a.ID,stuff(( SELECT ',' +BODY FROM body WHERE ID=a.ID FOR xml path( '' )),1,1, '' ) AS BODY |
15 |
FROM |
16 |
body a |
17 |
|
18 |
|
19 |
--具体思路是这样的: |
20 |
SELECT ',' +BODY FROM body WHERE ID=a.ID FOR xml path( '' ) |
21 |
--这条语句的作用是按照a中的ID查找body表中ID=a.ID的所有记录,并把它转换成一个xml(关于将查询集转换成xml的文章, |
22 |
--博客园有很多的,你可以去看看) |
23 |
stuff(( SELECT ',' +BODY FROM body WHERE ID=a.ID FOR xml path( '' )),1,1, '' ) |
24 |
--这条语句的作用是把生成的xml前面的一个逗号去掉并转化成标量值 |
25 |
--最后用一个distinct去掉重复的记录 |
解法二
使用游标,这里我定义了一个函数,你也可以改成存储过程之类的
01 |
USE MyTest |
02 |
go |
03 |
--自定义函数根据ID返回连接后的body(我的数据库名叫body) |
04 |
CREATE FUNCTION Getresult(@id int ) |
05 |
RETURNS nvarchar(20) |
06 |
AS |
07 |
BEGIN |
08 |
DECLARE @resultstr nvarchar(100),@tempstr nvarchar(20) |
09 |
DECLARE @tempid int |
10 |
DECLARE mycursor CURSOR |
11 |
FOR SELECT * FROM body |
12 |
OPEN mycursor |
13 |
FETCH next FROM mycursor INTO @tempid,@tempstr |
14 |
WHILE (@@FETCH_STATUS=0) |
15 |
BEGIN |
16 |
IF(@tempid=@id) |
17 |
BEGIN |
18 |
SET @tempstr=stuff(@tempstr,1,0, ',' ) |
19 |
SET @resultstr=stuff(@tempstr,1,0,@resultstr) |
20 |
END |
21 |
FETCH next FROM mycursor INTO @tempid,@tempstr |
22 |
END |
23 |
SET @resultstr=STUFF(@resultstr,1,1, '' ) |
24 |
CLOSE mycursor |
25 |
DEALLOCATE mycursor |
26 |
RETURN (@resultstr) |
27 |
END |
28 |
|
29 |
--函数建好后,执行以下SQL语句 |
30 |
SELECT distinct m.ID, dbo.Getresult(m.ID) AS BODY |
31 |
FROM |
32 |
body AS m |
三、说明
这里合并的字段都是字符串,下一次我会讨论如何对整形数字求和。