Designed by 77
加载资源 ......
感谢 ♥ 作者
先不感谢了

sql server的for xml path与变通的行转列

SQL Server中有提供一个FOR XML PATH的子句(不知道能不能叫函数),用来将查询结果行输出成XML格式,我们可以通过这个语法做一些变通实现一些特定的功能,比如说行转列。要会变通的话,当然首先是要知道FOR XML PATH的语法。

FOR XML PATH的简单语法

假设有一个hobby表(爱好),表中有两个字段,一个是hobbyID(爱好id),一个是hName(爱好名称)。

这样,我们执行一条最简单的带FOR XML PATH子句的SQL语句,看看查询出来的结果。

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格式。

FOR XML PATH的变通

更多的,FOR XML PATH子句是支持传递参数的,即FOR XML PATH(schema),这样的话在查询的时候就会将行标签<row>替换为<schema>,要注意的是schema必须是字符串。

SELECT * FROM hobby FOR XML PATH('yanggb');
<yanggb>
  <hobbyID>1</hobbyID>
  <hName>爬山</hName>
</yanggb>
<yanggb>
  <hobbyID>2</hobbyID>
  <hName>游泳</hName>
</yanggb>
<yanggb>
  <hobbyID>3</hobbyID>
  <hName>美食</hName>
</yanggb>

这时候,就可以利用XML的特点,即空标签不会存在的特定,将行标签<row>去掉。

SELECT * FROM hobby FOR XML PATH('');
<hobbyID>1</hobbyID>
<hName>爬山</hName>
<hobbyID>2</hobbyID>
<hName>游泳</hName>
<hobbyID>3</hobbyID>
<hName>美食</hName>

那能更改/去除行标签<row>,能不能更改/去除列标签呢?答案是可以的,可以通过给列起别名的方式来更改/除列标签。要注意的是这里的别名也必须是字符串。

SELECT hobbID AS AA, hName AS BB FROM hobby FOR XML PATH('');
<AA>1</AA>
<BB>爬山</BB>
<AA>2</AA>
<BB>游泳</BB>
<AA>3</AA>
<BB>美食</BB>

与去除行标签<row>的方式不一样的是,去除列标签不能将别名定义为空字符串,否则数据库引擎会报错误:[Err] 42000 - [SQL Server]缺少对象或列名,或者对象或列名为空。对于 SELECT INTO 语句,请确保每列均具有名称。对于其他语句,请查找空的别名。不允许使用定义为 "" 或 [] 的别名。请将别名更改为有效名称。

那么要怎么去除列标签呢,做法是给字段加上空字符串(加任何字符串都可以,我的理解是这种做法修改了列值,在没有起别名的情况下,原来的列标签不再匹配列值,数据库引擎会将自动该列标签去除)。

SELECT hobbID + '', hName + '' FROM hobby FOR XML PATH('');
1爬山2游泳3美食

FOR XML PATH实现行转列

根据上面的FOR XML PATH的变通的内容,我们就可以来实现行转列了。

SELECT
    hName, 
    (SELECT ',' + hName FROM hobby FOR XML PATH('')) AS hNames
FROM hobby FOR XML PATH('');

这样我们就能得到一个所有爱好拼接起来的列hNames。

这时候我们会发现hNames字段值多了一个逗号,使用STUFF函数(推荐)或REPLACE函数去除即可。

更多的,可以在FOR XML PATH子句前添加WHERE子句限定条件范围来限定行转列的范围(也可以使用自连接限定当前行转列的范围)。

当然了,SQL SERVER还提供了另外的行转列的PRIVOT函数和列转行的UNPRIVOT函数。

 

"一个姑娘不会因为你专一痴情就喜欢你,只会因为你优秀而喜欢你。"

posted @ 2019-06-15 11:10  yanggb  阅读(2401)  评论(0编辑  收藏  举报