那么还是首先来介绍一下FO

作者: 编程  发布:2019-09-26

一、SELECT

参考资料:

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

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

图片 1

        一.FOR XML PATH 简单介绍

        一.FOR XML PATH 简单介绍

select [ALL|DISTINCT] select_list[into new table]FROM table_source[where serch_conditaion][GROUP BY group_by_expression][Having serch_conditaion][Order by order_expression[ASC|DESC]]--从上面的语句可以看出SELECT 查询语句共有5个子句 其中SELECTFROM 为必选语句--SELECT 子句:用来指定由查询返回的列--ALL|DISTINCT:用来指定对查询结果集,相同行的处理方式,ALL-为所有 DISTINCT:保留一条记录--select_list:用来显示要显示的目标列,全部可以用 * 代替,不是全部每个列字段用,分割--into new table:用来创建一个新的临时表--FROM table_source:指定查询的数据源--where serch_conditaion:用来限定返回行的搜索条件--GROUP BY group_by_expression]:用来指定查到结果的分组条件--Having serch_conditaion:用来指定组成或聚合的搜索条件--Order by order_expression[ASC|DESC]:用来指定结果集的排序方式

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

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

图片 4

核心摘要

FOR XML PATH 的作用是把结果以xml文本的形式显示出来,也就是说,最终结果就是一个字符串,因此我们就不需要使用什么字符串合并函数了。

STUFF函数的原型是 Stuff(str1, start, len, str2),作用是,删掉str1中start开始的len个字符,用str2替换。因此,可以起到在多个项之间插入分隔符。

比如,

select ','+name from student for xml path('') group by class

输出结果可能是

,Jim,Kate,Tom,Sally

如果使用STUFF,可以删掉第一个空格

stuff(select ','+name from student for xml path('') group by class, 1, 1, '')

 

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

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

二、PIVOT 行转列

原文内容

-------------参考------------------------

----假设我们有如下数据表
------菜系表------------
--店名        菜系------
--澳门豆捞    川菜 
--澳门豆捞    粤菜 
--澳门豆捞    闽菜 
--为民大酒店  鲁菜 
--为民大酒店  粤菜 

SELECT * FROM @hobby FOR XML PATH

SELECT * FROM @hobby FOR XML PATH

注意:PIVOT、UNPIVOT是SQL Server 2005的语法,使用需修改数据库兼容级别
在数据库属性->选项->兼容级别改为 90

--为民大酒店  川菜

-------执行如下语句
select 店名,菜系=STUFF((select ','+ltrim(菜系) from 菜系表 where 店名=t.店名 for XML path('')),1,1,'')
from 菜系表 t
group by 店名

-------结果如下-------------
--店名        菜系----------
--澳门豆捞    川菜,闽菜,粤菜

       结果:

       结果:

PIVOT用于将列值旋转为列名,在SQL Server2000可以用聚合函数配合CASE语句实现

--为民大酒店  川菜,鲁菜,粤菜


Stuff(expression1_Str,startIndex,lengthInt,expression2_Str)函数共有四个参数,
其功能是将expression1_Str中自startIndex位置起删除lengthInt个字符,然后将expression2插入到expression1_Str中的startIndex位置。startIndex 从1开始
数据库表中有三个字段,要以xxxx-xxxxxx-xxxxxx的格式输出,其中不满相应位数的,在后面补空格,即把类似23,1234,879这样的三个数以如下形式输出到报表中:23__-1234__-879___的格式输出,标注颜色的下划线一种颜色代表一个空格。 
STUFF(SPACE(4),1,LEN(‘23’),’23’)+’-’+STUFF(SPACE(6),1,LEN(‘1234’),’1234’)+’-’+ STUFF(SPACE(6),1,LEN(‘879’),’879’),转换结果自然就为23__-1234__-879___了。
Stuff函数另一种解释
select stuff('string1',<starting position>,<length to delete from string 1>,'string2')
示例:
select stuff('youxiaofeng',2,1,'F')
从第二个字符开始,删掉一个字符,然后用'F'代替删掉字符的位置,如果不需要删掉字符,则将<length to delete from string 1>设为0即可。
注意:如果<starting position>或<length to delete from string 1 >是负的,或者<starting position>是大于<string 1>长度的数,则STUFF函数将返回NULL,如果指令的<length to delete from string 1>长于从<starting position>位置到<string 1>结尾的字符数,此函数将<string 1 >在<starting position-1>处截断


FOR XML PATH 语句的应用
大家都知道在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,下面是它的一些应用示例。

DECLARE @TempTable table(UserID int , UserName nvarchar(50));
insert into @TempTable (UserID,UserName) values (1,'a')
insert into @TempTable (UserID,UserName) values (2,'b')

select UserID,UserName from @TempTable FOR XML PATH
运行这段脚本,将生成如下结果:

<row>
<UserID>1</UserID>
<UserName>a</UserName>
</row>
<row>
<UserID>2</UserID>
<UserName>b</UserName>
</row>
大家可以看到两行数据生成了两个节点,修改一下PATH的参数:

select UserID,UserName from @TempTable FOR XML PATH('lzy')
再次运行上述脚本,将生成如下的结果:

<lzy>
<UserID>1</UserID>
<UserName>a</UserName>
</lzy>
<lzy>
<UserID>2</UserID>
<UserName>b</UserName>
</lzy>
可以看到节点变成,其实PATH() 括号内的参数是控制节点名称的,这样的话大家可以看一下如果是空字符串(不是没有参数)会是什么结果?

select UserID,UserName from @TempTable FOR XML PATH('')
执行上面这段脚本将生成结果:

<UserID>1</UserID>
<UserName>a</UserName>
<UserID>2</UserID>
<UserName>b</UserName>
这样就不显示上级节点了,大家知道在 PATH 模式中,列名或列别名被作为 XPath 表达式来处理,也就是说,是列的名字,这样大胆试验一下不给指定列名和别名会是怎么样?

select CAST(UserID AS varchar) + '',UserName + '' from @TempTable FOR XML PATH('')
运行上面这句将生成结果

1a2b

所有数据都生成一行,而且还没有连接字符,这样的数据可能对大家没有用处,还可以再变化一下:

select CAST(UserID AS varchar) + ',',UserName + '',';' from @TempTable FOR XML PATH('')
生成结果

1,a;2,b;

大家现在明白了吧,可以通过控制参数来生成自己想要的结果,例如:

select '{' + CAST(UserID AS varchar) + ',','"' +UserName + '"','}' from @TempTable FOR XML PATH('')
生成结果

{1,"a"}{2,"b"}

还可以生成其他格式,大家可以根据自己需要的格式进行组合。

下面是一个数据统计的应用,希望大家可以通过下面的实例想到更多的应用

DECLARE @T1 table(UserID int , UserName nvarchar(50),CityName nvarchar(50));
insert into @T1 (UserID,UserName,CityName) values (1,'a','上海')
insert into @T1 (UserID,UserName,CityName) values (2,'b','北京')
insert into @T1 (UserID,UserName,CityName) values (3,'c','上海')
insert into @T1 (UserID,UserName,CityName) values (4,'d','北京')
insert into @T1 (UserID,UserName,CityName) values (5,'e','上海')

SELECT B.CityName,LEFT(UserList,LEN(UserList)-1) FROM (
SELECT CityName,
(SELECT UserName+',' FROM @T1 WHERE CityName=A.CityName FOR XML PATH('')) AS UserList
FROM @T1 A 
GROUP BY CityName
) B
生成结果(每个城市的用户名)

北京 b,d
上海 a,c,e

 

图片 5

图片 6

PIVOT的一般语法是:PIVOT FOR 列 in )AS P

灵活运用 SQL SERVER FOR XML PATH

 

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

        一.FOR XML PATH 简单介绍

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

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

SELECT * FROM @hobby FOR XML PATH

       结果:

图片 8

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

图片 9

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

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

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

 

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

图片 10

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

图片 11

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

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

 

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

图片 12

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

图片 13

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

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列存学生的爱好!那么现在表结构如下:

           图片 14

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

图片 15

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 

图片 16

         结果如下:图片 17

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

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

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

那么接着看:

图片 18

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  

图片 19

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

图片 20

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

好啦,太晚啦就说到这里吧!

 

 

 

 

 

 

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

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

完整语法:

图片 21

图片 22

table_source --数据源

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

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

PIVOT(

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

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

聚合函数(value_column) --统计转化行值的聚合函数值

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

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

FOR pivot_column --需要转化的行列名

 

 

IN(<column_list>) --行值得结合

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

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

)

图片 23

图片 24

典型实例:

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

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

图片 25

图片 26

图片 27

1、建立表格ifobject_idisnotnulldroptabletbgocreate table tb (姓名varchar,课程varchar,分数int)insert into tb values ('张三','语文',74)insert into tb values ('张三','数学',83)insert into tb values ('张三','物理',93)insertintotbvalues ('李四','语文',74)insert into tb values ('李四','数学',84)insert into tb values ('李四','物理',94)goselect * from tbgo姓名       课程       分数---------- ---------- -----------张三       语文        74张三       数学        83张三       物理        93李四       语文        74李四       数学        84李四       物理        94 2、使用SQL Server 2000静态SQL--cselect姓名, max(case 课程 when '语文' then 分数 else 0 end)语文, max(case 课程 when '数学' then 分数 else 0 end)数学, max(case 课程 when '物理' then 分数 else 0 end)物理from tbgroup by 姓名姓名       语文        数学        物理---------- ----------- ----------- -----------李四        74          84          94张三        74          83          93 3、使用SQL Server 2005静态SQLselect*fromtb pivotfor课程in)a

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

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

图片 28

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

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

三、

 

 

UNPIVOT用于将列明转为列值,在SQL Server 2000可以用UNION来实现

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

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

完整语法:

图片 29

图片 30

table_source --数据源 转化后的表结构查询 例如:select 姓名,课程,分数 from tb1

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

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

UNPIVOT(

图片 31

图片 32

value_column --列值(本身列名的值 如:语文 列 值 83 ) 例如:分数

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

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

FOR pivot_column --列名 (集合列转成行后的名字 例如:课程)

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

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

IN(<column_list>) --集合参数(例如:[语文],[数学],[物理])

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

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

)

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

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

示例:

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

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

图片 33

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

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

create table tb(姓名varchar,语文int,数学int,物理int)insert into tb values('张三',74,83,93)insert into tb values('李四',74,84,94)goselect  *from tbgo姓名       语文        数学        物理---------- ----------- ----------- -----------张三       74          83          93李四        74          84          94 2、使用SQL Server 2000静态SQL--SQL SERVER 2000静态SQL。select*from( select 姓名,课程='语文',分数=语文 from tb union all select姓名,课程='数学',分数=数学 from tb union all select姓名,课程='物理',分数=物理 from tb) torder b y 姓名,case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end姓名       课程 分数---------- ---- -----------李四       语文 74李四       数学 84李四       物理 94张三       语文 74张三       数学 83张三       物理 932、使用SQL Server 2005静态SQL--SQL SERVER 2005动态SQLselect 姓名,课程,分数 from tb unpivot ( 分数 for 课程 in([语文],[数学],[物理])) t

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

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

图片 34

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

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

四、``merge 用于2张表更新的常用关键字

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

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

基本语法:

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

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

MERGE  table         --要匹配的目标表 a
using  scourtb       --查询的源数据或者元数据表名 b
on  conditaion        --元数据与目标表的匹配条件 
whenmatchedthen     --匹配成功  updateseta.字段=X  --一般匹配成功都是执行更新
whennotmatchedthen --匹配不成功 insertvalues(对应的值); --执行插入 向目标表插入元数据的新数据
WHEN NOT MATCHED BY SOURCE THENDELETE; -- 目标表有,源表没有,目标表该数据删除.

示例:

           图片 35

           图片 36

图片 37

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

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

create table employee(empid integer,fname nvarchar,lname nvarcharinsert into employeeselect 2021110,'小','张' insert into employeeselect 2021110,'小','李'  create table test(id integer,num integer) insert into testselect 2021110,2 insert into testselect 2,2  期望结果语句:select * from  employee2021110,'大','张'2021110,'大','李'2,'大','大'

图片 38

图片 39

图片 40

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 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 

SQL语句实现:

图片 41

图片 42

图片 43

         结果如下:图片 44

         结果如下:图片 45

merge into  employee a   using  test b   on   b.id = a.empid    when matched then     update set a.fname= '大'   when not matched then   insert values (id,'大','大');  end   exec test_mergeselect * from employee /*empid       fname                lname----------- -------------------- --------------------2021110     大                    张2021110     大                    李2           大                    大 

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

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

图片 46

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

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

五、sql STUFF用法

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

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

1、作用

那么接着看:

那么接着看:

删除指定长度的字符,并在指定的起点处插入另一组字符。

图片 47

图片 48

2、语法

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 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  

STUFF ( character_expression , start , length ,character_expression )

图片 49

图片 50

3、示例

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

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

以下示例在第一个字符串 abcdef 中删除从第 2 个位置开始的三个字符,然后在删除的起始位置插入第二个字符串,从而创建并返回一个字符串

图片 51

图片 52

SELECT STUFF('abcdef', 2, 3, 'ijklmn')
GO

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

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

下面是结果集

好啦,太晚啦就说到这里吧!

aijklmnef

4、参数
character_expression

一个字符数据表达式。character_expression 可以是常量、变量,也可以是字符列或二进制数据列。

start

一个整数值,指定删除和插入的开始位置。如果 start 或 length 为负,则返回空字符串。如果 start 比第一个 character_expression长,则返回空字符串。start 可以是 bigint 类型。

length

一个整数,指定要删除的字符数。如果 length 比第一个 character_expression长,则最多删除到最后一个 character_expression 中的最后一个字符。length 可以是 bigint 类型。

5、返回类型
如果 character_expression 是受支持的字符数据类型,则返回字符数据。如果 character_expression 是一个受支持的 binary 数据类型,则返回二进制数据。

6、备注
如果结果值大于返回类型支持的最大值,则产生错误。

六、sql for xml path用法

一.FOR XML PATH 简单介绍

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

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

SELECT*FROM@hobbyFORXMLPATH

结果:

图片 54图片 55图片 56<row>
<hobbyID>1</hobbyID>
<hName>爬山</hName>
</row>
<row>
<hobbyID>2</hobbyID>
<hName>游泳</hName>
</row>
<row>
<hobbyID>3</hobbyID>
<hName>美食</hName>
</row>图片 57图片 58图片 59

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

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

SELECT*FROM@hobbyFORXMLPATH('MyHobby')

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

图片 60图片 61图片 62<MyHobby>
<hobbyID>1</hobbyID>
<hName>爬山</hName>
</MyHobby>
<MyHobby>
<hobbyID>2</hobbyID>
<hName>游泳</hName>
</MyHobby>
<MyHobby>
<hobbyID>3</hobbyID>
<hName>美食</hName>
</MyHobby>图片 63图片 64图片 65

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

SELECThobbyIDas'MyCode',hNameas'MyName'FROM@hobbyFORXMLPATH('MyHobby')

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

图片 66图片 67图片 68<MyHobby>
<MyCode>1</MyCode>
<MyName>爬山</MyName>
</MyHobby>
<MyHobby>
<MyCode>2</MyCode>
<MyName>游泳</MyName>
</MyHobby>
<MyHobby>
<MyCode>3</MyCode>
<MyName>美食</MyName>
</MyHobby>图片 69图片 70图片 71

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

SELECT'['+hName+']'FROM@hobbyFORXMLPATH

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

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

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

SELECT'{'+STR+'}','['+hName+']'FROM@hobbyFORXMLPATH

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

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

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

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

图片 72

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

图片 73图片 74图片 75SELECTB.sName,LEFT(StuList,LEN-1)ashobbyFROM(
SELECTsName,
(SELECThobby+','FROMstudent
WHEREsName=A.sName
FORXMLPATHASStuList
FROMstudentA
GROUPBYsName
)B图片 76图片 77图片 78

结果如下:图片 79

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

SELECThobby+','FROMstudent
WHEREsName=A.sName
FORXMLPATH

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

那么接着看:

图片 80图片 81图片 82SELECTB.sName,LEFT(StuList,LEN-1)ashobbyFROM(
SELECTsName,
(SELECThobby+','FROMstudent
WHEREsName=A.sName
FORXMLPATHASStuList
FROMstudentA
GROUPBYsName
)B图片 83图片 84图片 85

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

图片 86

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

也可以这样写:

select NAME,
STUFF((select ','+fv+'' from #TEMP tb1 where tb1.name=tb.name for xml path,1,1,'') as fv --截取查询的结果集合,替换第一个字符
from #TEMP as tb group by tb.NAME

三、关于主从表关联取从表最大数据一条记录问题

select a.*,b.* FROM dbo.SQ_AJBL AS a
left join SQ_AJBLWorkFlow AS b on a.gID=b.gPID
where b.dCreateDate IN (select max(dCreateDate) from SQ_AJBLWorkFlow GROUP BY gPID)

本文由9159.com发布于编程,转载请注明出处:             那么还是首先来介绍一下FO

关键词:

上一篇:没有了
下一篇:没有了