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 条评论
登录 后参与评论

相关文章

来自专栏一枝花算不算浪漫

[Java面试三]JavaWeb基础知识总结.

4269
来自专栏晨星先生的自留地

面试中遇到的坑之mysql注入入门

1904
来自专栏GreenLeaves

Oracle 分页查询

本文使用到的是oracle数据库scott方案所带的表,scott是oracle数据库自带的方案,使用前请确保其解锁 ? Oracle分页一共有三种 1、使用r...

2078
来自专栏MySQL实战分享

MySQL 经典案例分析:Specified key was too long

BG 内部要进行数据库的容灾演习,需要模拟线上实际的环境进行测试,这就需要 copy 一份线上的数据库到测试库中,其实也就是重建一个线上数据库。要完成这个任务其...

3.6K6
来自专栏大内老A

创建代码生成器可以很简单:如何通过T4模板生成代码?[上篇]

在《基于T4的代码生成方式》中,我对T4模板的组成结构、语法,以及T4引擎的工作原理进行了大体的介绍,并且编写了一个T4模板实现了如何将一个XML转变成C#代码...

4018
来自专栏有趣的Python

Scrapy分布式爬虫打造搜索引擎 - (三)知乎网问题和答案爬取Python分布式爬虫打造搜索引擎

Python分布式爬虫打造搜索引擎 基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站 三、知乎网问题和答案爬取 ...

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

简单分析shared pool(三) (r5笔记第94天)

提到shared pool,都会不由得和sql语句的解析过程联系起来,因为shared pool所做的主要工作就是解析sql语句,生成执行计划,在之前的两篇中...

2727
来自专栏数据和云

Oracle 数据库之最:你见过最高的 SQL Version 是多少?

Oracle数据库中执行的SQL,很多时候会因为种种原因产生多个不同的执行版本,一个游标的版本过多很容易引起数据库的性能问题,甚至故障。 有时候一个SQL的版本...

2835
来自专栏PingCAP的专栏

十分钟成为 Contributor 系列:重构内建函数进度报告

为了方便社区同学更好地参与 TiDB 项目,本文一方面对继上一篇文章发布后参考社区的反馈对表达式计算框架所做的修改进行详细介绍,另一方面对尚未重写的 built...

1050
来自专栏漫漫前端路

巧用 TypeScript(二)

Decorator 早已不是什么新鲜事物。在 TypeScript 1.5 + 的版本中,我们可以利用内置类型 ClassDecorator、PropertyD...

612

扫码关注云+社区