昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行

比如表中有两列数据 :

ep_classes  ep_name

AAA         企业1

AAA         企业2

AAA         企业3

BBB         企业4

BBB         企业5

我想把这个表变成如下格式:

ep_classes      ep_name

AAA             企业1,企业2,企业3

BBB             企业4,企业5

一开始挺头疼的(会了的肯定没有这种感觉,不会那必须是头疼啊(*^__^*) ),从网上找了点资料,算是找到一种比较简单方便的方法吧,现在大体总结一下,供大家共同学习。

原先的表名为:ep_detail。

实现代码如下:

select ep_classes, ep_name = (stuff((select ',' + ep_name from ep_detail where ep_classes =
a.ep_classes for xml path('')),1,1,'')) from ep_detail a group by ep_classes

这里使用了SQL Server 2005版本以后加入的stuff以及for xml path,先说下在上面这句sql中的作用,然后再详细的说明一下这两个的用法。

for xml path('')

这句是把拼接的内容的第一个“,”去掉。

好了,现在开始具体说一下用法:

①stuff:
1、作用
stuff(param1, startIndex, length, param2)
将param1中自startIndex(SQL中都是从1开始,而非0)起,删除length个字符,然后用param2替换删掉的字符。

2、参数
param1
一个字符数据表达式。param1可以是常量、变量,也可以是字符列或二进制数据列。
startIndex
一个整数值,指定删除和插入的开始位置。如果 startIndex或 length 为负,则返回空字符串。如果startIndex比param1长,则返回空字符串。startIndex可以是 bigint 类型。
length 
一个整数,指定要删除的字符数。如果 length 比param1长,则最多删除到param1 中的最后一个字符。length 可以是 bigint 类型。

3、返回类型
如果param1是受支持的字符数据类型,则返回字符数据。如果param1是一个受支持的 binary 数据类型,则返回二进制数据。
4、备注
如果结果值大于返回类型支持的最大值,则产生错误。

eg:

select STUFF('abcdefg',1,0,'1234')       --结果为'1234abcdefg'
select STUFF('abcdefg',1,1,'1234') --结果为'1234bcdefg'
select STUFF('abcdefg',2,1,'1234') --结果为'a1234cdefg'
select STUFF('abcdefg',2,2,'1234') --结果为'a1234defg'

通过以上4个小例子,应该能明白stuff的用法了。

②for xml path:

for xml path有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作。那么以一个实例为主.

我们还是通过列子引入:

假设有个表存放着学生的选课情况(stu_courses):

接下来我们来看应用FOR XML PATH的查询结果语句如下:

select stu_name,stu_course from stu_courses for xml path;

结果如下:

<row>
<stu_name>张三</stu_name>
<stu_course>数学</stu_course>
</row>
<row>
<stu_name>张三</stu_name>
<stu_course>语文</stu_course>
</row>
<row>
<stu_name>张三</stu_name>
<stu_course>英语</stu_course>
</row>
<row>
<stu_name>李四</stu_name>
<stu_course>数学</stu_course>
</row>
<row>
<stu_name>李四</stu_name>
<stu_course>语文</stu_course>
</row>

由此可以看出 FOR XML PATH 可以将查询结果根据行输出成XML各式!而且我们还可以改变XML行节点的名称,代码如下:

select stu_name,stu_course from stu_courses for xml path('course');

看显示结果,原来的行节点<row> 变成了我们在PATH后面括号()中自定义的名称<course>:

<course>
<stu_name>张三</stu_name>
<stu_course>数学</stu_course>
</course>
<course>
<stu_name>张三</stu_name>
<stu_course>语文</stu_course>
</course>
<course>
<stu_name>张三</stu_name>
<stu_course>英语</stu_course>
</course>
<course>
<stu_name>李四</stu_name>
<stu_course>数学</stu_course>
</course>
<course>
<stu_name>李四</stu_name>
<stu_course>语文</stu_course>
</course>

其实我们还可以改变列节点,还记的给列起别名的关键字AS吗?就是用它!代码如下:

select stu_name as MyName,stu_course as MyCourse from stu_courses for xml path('course');

显示结果:

<course>
<MyName>张三</MyName>
<MyCourse>数学</MyCourse>
</course>
<course>
<MyName>张三</MyName>
<MyCourse>语文</MyCourse>
</course>
<course>
<MyName>张三</MyName>
<MyCourse>英语</MyCourse>
</course>
<course>
<MyName>李四</MyName>
<MyCourse>数学</MyCourse>
</course>
<course>
<MyName>李四</MyName>
<MyCourse>语文</MyCourse>
</course>

我们还可以构建我们喜欢的输出方式,看代码

select '['+stu_name+','+stu_course+']' from stu_courses for xml path('');

显示结果

1
[张三,数学][张三,语文][张三,英语][李四,数学][李四,语文]

* ================================================================================================
*
补充:子表求和再拼接:
*
================================================================================================

USE tempdb
GO
IF OBJECT_ID('dbo.[t]') IS NOT NULL
DROP TABLE dbo.[t]
GO
CREATE TABLE dbo.[t](
[ID] INT
,[Location] NVARCHAR(20)
,[quantity] FLOAT
,[Company] NVARCHAR(10)
)
GO
SET NOCOUNT ON
INSERT INTO dbo.[t] VALUES(N'1',N'aa',N'10',N'包')
INSERT INTO dbo.[t] VALUES(N'1',N'bb',N'10',N'箱')
INSERT INTO dbo.[t] VALUES(N'2',N'aaa',N'1',N'箱')
INSERT INTO dbo.[t] VALUES(N'2',N'bbb',N'20',N'箱')
INSERT INTO dbo.[t] VALUES(N'2',N'ccc',N'15',N'箱')
INSERT INTO dbo.[t] VALUES(N'2',N'aaa',N'1.5',N'箱')
INSERT INTO dbo.[t] VALUES(N'2',N'aaa',N'27',N'包')
----------- 以上为测试表及测试数据 ----------------- SELECT ID
,
STUFF((
SELECT ','+ b.Location+'-'+LTRIM(SUM([quantity]))+[Company]
FROM t AS b WHERE a.id=b.id
GROUP BY b.Location,[Company]
FOR XML PATH('')
),1,1,'') AS describe
FROM t AS a
GROUP BY ID
/*
ID describe
1 aa-10包,bb-10箱
2 aaa-27包,aaa-2.5箱,bbb-20箱,ccc-15箱

【转载】SQL SERVER 将多行数据合并成一行的更多相关文章

  1. SQL SERVER将多行数据合并成一行(转载)

    昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行 比如表中有两列数据 : ep_classes  ep_name A ...

  2. SQL SERVER将多行数据合并成一行(转)

    1)比如表中有三列数据: 2)执行如下查询: 1 SELECT [USER_NAME], [USER_ACCOUNT] 2 , [ROLE_NAME] = stuff(( 3 SELECT ',' + ...

  3. SQL SERVER将多行数据合并成一行

    1)比如表中有三列数据: 2)执行如下查询: SELECT [USER_NAME], [USER_ACCOUNT] , [ROLE_NAME] = stuff(( SELECT ',' + [ROLE ...

  4. sql查询 ,多行数据合并成一行,并且显示合并后某一列的值拼接结果

    select  [value] = stuff((select ','+modmb003  from modmb detail where modmb=18 for xml path('')), 1, ...

  5. SQL将多行数据合并成一行【转】

    转:https://blog.csdn.net/AntherFantacy/article/details/83824182 今天同事问了一个需求,就是将多行数据合并成一行进行显示,查询了一些资料,照 ...

  6. 使用Notepad++将多行数据合并成一行

    1.按Ctrl+F,弹出“替换”的窗口: 2.选择“替换”菜单: 3.“查找目标”内容输入为:\r\n: 4.“替换为”内容为空: 5.“查找模式”选择为正则表达式: 6.设置好之后,点击“全部替换” ...

  7. sql里将重复行数据合并为一行,数据用逗号分隔

    一.定义表变量 DECLARE @T1 table ( UserID int , UserName ), CityName ) ); ,'a','上海') ,'b','北京') ,'c','上海') ...

  8. SQL Server中将多行数据拼接为一行数据(一个字符串)

    表A中id与表B中aid为一对多的关系 例如: 表A: id name a1 tom a2 lily a3 lucy 表B: id aid value b1 a1 B1 b2 a1 B2 b3 a2 ...

  9. SQL Server中将多行数据拼接为一行数据并且有特殊字符

    有表结构如下: 这时,要求显示所有学生的爱好的结果集,代码如下: ) as hobby FROM ( SELECT name, (SELECT hobby+',' FROM student WHERE ...

随机推荐

  1. MergeOption.NoTracking的使用

    前两天项目维护出现一个bug,报错信息是提交出错:AcceptChanges 无法继续,因为该对象的键值与 ObjectStateManager 中的另一个对象冲突.请在调用 AcceptChange ...

  2. ExceptionHandler配合RestControllerAdvice全局处理异常

    Java全局处理异常 引言 对于controller中的代码,为了保证其稳定性,我们总会对每一个controller中的代码进行try-catch,但是由于接口太多,try-catch会显得太冗杂,s ...

  3. PhpStorm 2020.1.2破解 | JetBrains PhpStorm 2020.1.2破解版 附破解文件

    直接去官网下载 2020.1.2的版本,版本一定要对得上  是2020.1.2版本 下面是破解的jar,几兆而已 --------------------- 链接:https://pan.baidu. ...

  4. 蓝桥杯赛前复习C++

    C标准库常用函数 memset函数:暴力清空 void *memset(void *str, int c, size_t n) str -- 指向要填充的内存块. c -- 要被设置的值.该值以 in ...

  5. FastApi学习

    vscode配置 插件 code runner在 setting.json中关于python的修改为,因为我使用了虚拟环境,得让vscode找到python的路径 "code-runner. ...

  6. dockerNginx代理本地目录

    dockerNginx代理本地目录 ssl_certificate cert/5900588_test.zk.limengkai.work.pem; ssl_certificate_key cert/ ...

  7. mindxdl---common--test_tools.go

    // Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common define co ...

  8. mysql 基础明细

    1.mysql 没有 TOP,用limit实现 2.mysql having 聚合之后,对组操作,和GROUP By搭配 mysql where  聚合之前,对表和视图操作 3.where 子句的作用 ...

  9. CentOS 7.x字符界面安装图形界面方法

    1. 配置好yum源,可以使用光盘镜像源,也可以使用网络源. 阿里源下载示例: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.ali ...

  10. bugku 备份是个好习惯

    打开是一段神秘代码,我也不知道是什么 直接解密试试 尝试各种,发现是md5,解开是.... 可能需要我们传什么东西进去,抓包看看,无果.... 看看题目是备份,可能这道题就和备份文件有关 我就直接点了 ...