一、问题
有表如下:
如何获得如下结果:
二、解法一
使用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 |
三、说明
这里合并的字段都是字符串,下一次我会讨论如何对整形数字求和。