示例

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

类别 名称
AAA 企业1
AAA 企业2
AAA 企业3
BBB 企业4
BBB 企业5

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

类别 名称
AAA 企业1,企业2,企业3
BBB 企业4,企业5

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

原先的表名为Table_A,实现代码如下:

select 类别, 名称 = (stuff((select ',' + 名称 from Table_A where 类别 = A.类别 for xml path('')),1,1,''))
from Table_A as A group by 类别

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

for xml path('') 

这句是把得到的内容以XML的形式显示。

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

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

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 类型。
  • param2,返回类型。如果param1是受支持的字符数据类型,则返回字符数据。如果param1是一个受支持的 binary 数据类型,则返回二进制数据。

示例

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'

for xml path

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

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

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

select stu_name,stu_course from stu_courses for xml path;

结果如下:

由此可以看出 FOR XML PATH 可以将查询结果根据行输出成XML各式!

一.FOR XML PATH 简单介绍

那么还是首先来介绍一下FOR XML PATH ,假设现在有一张兴趣爱好表(hobby)用来存放兴趣爱好,表结构如下:

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

SELECT * FROM @hobby FOR XML PATH

结果:

<row>
  <hobbyID>1</hobbyID>
  <hName>爬山</hName>
</row>
<row>
  <hobbyID>2</hobbyID>
  <hName>游泳</hName>
</row>
<row>
  <hobbyID>3</hobbyID>
  <hName>美食</hName>
</row>

由此可见FOR XML PATH 可以将查询结果根据行输出成XML各式!

那么,如何改变XML行节点的名称呢?代码如下:

SELECT * FROM @hobby FOR XML PATH('MyHobby')

结果一定也可想而知了吧?没错原来的行节点<row> 变成了我们在PATH后面括号()中,自定义的名称<MyHobby>,结果如下:

<MyHobby>
  <hobbyID>1</hobbyID>
  <hName>爬山</hName>
</MyHobby>
<MyHobby>
  <hobbyID>2</hobbyID>
  <hName>游泳</hName>
</MyHobby>
<MyHobby>
  <hobbyID>3</hobbyID>
  <hName>美食</hName>
</MyHobby>

这个时候细心的朋友一定又会问那么列节点如何改变呢?还记的给列起别名的关键字AS吗?对了就是用它!代码如下:

SELECT hobbyID as 'MyCode',hName as 'MyName' FROM @hobby FOR XML PATH('MyHobby')

那么这个时候我们列的节点名称也会编程我们自定义的名称 <MyCode>与<MyName>结果如下:

<MyHobby>
  <MyCode>1</MyCode>
  <MyName>爬山</MyName>
</MyHobby>
<MyHobby>
  <MyCode>2</MyCode>
  <MyName>游泳</MyName>
</MyHobby>
<MyHobby>
  <MyCode>3</MyCode>
  <MyName>美食</MyName>
</MyHobby>

噢! 既然行的节点与列的节点我们都可以自定义,我们是否可以构建我们喜欢的输出方式呢?还是看代码:

SELECT '[ '+hName+' ]' FROM @hobby FOR XML PATH('')

没错我们还可以通过符号+号,来对字符串类型字段的输出格式进行定义。结果如下:

[ 爬山 ][ 游泳 ][ 美食 ]

那么其他类型的列怎么自定义? 没关系,我们将它们转换成字符串类型就行啦!例如:

SELECT '{'+STR(hobbyID)+'}','[ '+hName+' ]' FROM @hobby FOR XML PATH('')

好的 FOR XML PATH就基本介绍到这里吧,更多关于FOR XML的知识请查阅帮助文档!

接下来我们来看一个FOR XML PATH的应用场景吧!那么开始吧。。。。。。

二.一个应用场景与FOR XML PATH应用

首先呢!我们在增加一张学生表,列分别为(stuID,sName,hobby),stuID代表学生编号,sName代表学生姓名,hobby列存学生的爱好!那么现在表结构如下:

这时,我们的要求是查询学生表,显示所有学生的爱好的结果集,代码如下:

SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby FROM (
SELECT sName,
(SELECT hobby+',' FROM student 
  WHERE sName=A.sName 
  FOR XML PATH('')) AS StuList
FROM student A 
GROUP BY sName
) B 

结果如下:

分析: 好的,那么我们来分析一下,首先看这句:

SELECT hobby+',' FROM student 
  WHERE sName=A.sName 
  FOR XML PATH('')

这句是通过FOR XML PATH 将某一姓名如张三的爱好,显示成格式为:“ 爱好1,爱好2,爱好3,”的格式!

那么接着看:

SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby FROM (
SELECT sName,
(SELECT hobby+',' FROM student 
  WHERE sName=A.sName 
  FOR XML PATH('')) AS StuList
FROM student A 
GROUP BY sName
) B  

剩下的代码首先是将表分组,在执行FOR XML PATH 格式化,这时当还没有执行最外层的SELECT时查询出的结构为:

可以看到StuList列里面的数据都会多出一个逗号,这时随外层的语句:SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby  就是来去掉逗号,并赋予有意义的列明!

SQL之 Stuff和For xml path相关推荐

  1. 灵活运用 SQL Server 数据库的 FOR XML PATH

    起因¶ 今天欧阳冰提出一个报表需求,其核心部分可以简化为这样一张表格: 调度单号 与调度单相关的多张作业单号 001 0001/0002/0003 002 0004 003 0005/0006/000 ...

  2. 使用 FOR XML PATH 合并SQL Server查询结果的重复行

    参考资料: http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html http://www.cnblogs.com/code ...

  3. SQL Server FOR XML PATH 语句的应用

    在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,下面是它的一些应用示例. DECLARE @TempTable table(UserID int , Use ...

  4. SQL Server FOR XML PATH 语句的应用---列转行

    经常在论坛看到高手使用了 for xml path,由于是搜索一下,记录了详细的使用方法. 在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,下面是它的一些应 ...

  5. sql limit 子句_SQL Server中的FOR XML PATH子句

    sql limit 子句 As SQL professionals, we often have to deal with XML data in our databases. This articl ...

  6. 将SQL for xml path('')中转义的字符正常显示

    将SQL for xml path('')中转义的字符正常显示 在工作中出现的发送邮件的时候:因为邮件内容中有链接,并且多个拼接在一起的,于是用了for xml path().        但是,这 ...

  7. sql server 利用 For Xml Path('') 多行数据拼接成一个字符串

    注意:这里有一种可能被弃用的方法,微软真他么坑死了,我的版本是19的,以前可以用,现在不行了 方法一(弃用): SELECT(SELECT CAST(bs_id AS VARCHAR(50)) + ' ...

  8. SQL中的for xml path

    点击关注"SQL数据库开发", 设为"置顶或星标",第一时间送达干货 最近出的每日一题里面,有一道是关于合并同类型数据为一行的题,使用SQL Server 20 ...

  9. SQL将查询结果合并到一个字段中并使用,分割,不使用GROUP_CONCAT和FOR XML PATH(‘‘)与存储过程

    需求背景: 项目中使用一个字段保存了外键信息,多个外键用[,](逗号)分割,在进行查询的时候需要将这些关联的外键相关字段查询出来. 如我有一个班级表,表中保存了班级班主任信息,班主任可以是多个人,多个 ...

最新文章

  1. LeetCode 15. 3Sum--Java,Python解法
  2. JavaCodeTra 猴子选猴王 约瑟夫循环
  3. 计算机研发部门职责,计算机研发岗位职责
  4. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q40-Q44)
  5. Spring Security源码分析四:Spring Social实现微信社交登录
  6. 【软件测试】软件测试札记
  7. idea整合EasyCode基于lombok和swagger自定义模板
  8. 回溯算法解迷宫问题(java版)
  9. 微信小程序-colorUI组件库
  10. socket用起始码分割_编码器基础——格雷码的编码美学
  11. html中复选框只能选一个,HTML选择三个不同的复选框并显示它们
  12. Failed to process import candidates for configuration class :Annotation-specified bean name ‘XXX‘ fo
  13. H3C交换机端口链路聚合
  14. 用计算机数字表白,数字表白公式 表白套路情话
  15. NEUQ ACM预备队训练-week5(图的基础存图和dfs)
  16. 谷歌浏览器F12抓包如何过滤只显示接口请求不显示图片、js那些请求
  17. Docker系列之常用命令操作手册
  18. 利用VMware虚拟机将Ubuntu18.04装入U盘或移动硬盘,实现UbuntuToGo,随插随用,支持UEFI启动(附ROS安装的相关链接)
  19. 海信电视黑屏出现android,海信智能电视开机黑屏原因和解决办法
  20. MEMS传感器中的小型化_凯利讯半导体

热门文章

  1. windows下将iso文件挂载到文件夹
  2. win7+iis7.5下的asp.net网站发布系列问题
  3. 双花证明已实现,BCH安全的0确认交易还远吗?
  4. [Android]手动触发OnClick事件
  5. 在Mac OS X macOS Sierra上进行VirtualBox和GNS3链接
  6. C++中operator关键字(重载操作符)
  7. Java多线程面试题
  8. mysql单机多实例——方法1
  9. Hibernate智能化分页
  10. java中static作用详解