sqlserver - 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  就是来去掉逗号,并赋予有意义的列明!

以上转载自:http://www.cnblogs.com/doubleliang/archive/2011/07/06/2098775.html

如下应用:

city表:

user表:

查询cityIds对应的city name,如下:

解决sql:

SELECT TOP 1000 [id]
      ,[userName]
      ,[password]
      ,[isLock]
      ,[isAdmin]
      ,[nickName]
      ,[createTime]
      ,[cityIds],(select STUFF((select ',' + Convert(varchar(50),name) FROM city where charindex(','+rtrim(id)+',', ','+cityIds+',')>0  FOR XML PATH('')),1,1,'')) as cityNames
  FROM [userInfo]

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

python数据处理实战-自动统计mysql数据库数据表每天数据量

日常报表统计,日总量,日增量不可避免,这篇文章我们从实际应用出发,从逻辑思考到最后写出代码,一步步分析拆解 一.表结构设计 既然想统计每一张表每天的数据量,后续...

4057
来自专栏Rgc

mysql数据库优化(三)--分区

分区:把一个数据表的文件和索引分散存储在不同的物理文件中。 特点:业务层透明,无需任何修改,即使从新分表,也是在mysql层进行更改(业务层代码不动)

1153
来自专栏性能与架构

Mysql group by实现方式(一) - 临时表

当MySQL Query Optimizer无法找到可以利用的合适索引时,就不得不先读取需要的数据,然后通过临时表来完成GROUP BY操作 例如 EXPLAI...

2746
来自专栏技术记录

mySQL优化方案

1、选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得...

1928
来自专栏Python

异常处理:1215 - Cannot add foreign key constraint

  最近在做新生入学系统,学生表中包括新生的班级,专业等信息,班级,专业就需要和班级表,专业表进行关联,但是在添加外键的过程中却出现了“Cannot add f...

21610
来自专栏idba

MySQL 各种SQL语句加锁分析

Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),UPDATE以及DE...

922
来自专栏JAVA烂猪皮

用 Node + MySQL 如何处理 100G 数据

通过这个 Node.js 和 MySQL 示例项目,我们将看看如何有效地处理 数十亿行 占用 数百GB 存储空间的数据。

1695
来自专栏杨建荣的学习笔记

MySQL自增列的重复值问题(r12笔记第25天)

如果需要把一台MySQL中的数据定期归档到另外一台MySQL历史库中,那么很可能会发现会有重复值的问题,导致数据导入会失败,而这个问题其实是和自增列的重复...

3356
来自专栏潘昌伟的专栏

用好 mysql 分区表

大数据时代,数据量趋于海量,mysql单表很难满足大数据场景的一些统计需求,用好分区表可以很好的解决很大一部分的问题。

1.4K0
来自专栏黑泽君的专栏

在命令行下,Mysql显示各个端所使用的字符集命令

582

扫码关注云+社区