SQL Server中有提供一个FOR XML PATH的子句(不知道能不能叫函数),用来将查询结果行输出成XML格式,咱们能够经过这个语法作一些变通实现一些特定的功能,好比说行转列。要会变通的话,固然首先是要知道FOR XML PATH的语法。数据库
FOR XML PATH的简单语法函数
假设有一个hobby表(爱好),表中有两个字段,一个是hobbyID(爱好id),一个是hName(爱好名称)。spa
这样,咱们执行一条最简单的带FOR XML PATH子句的SQL语句,看看查询出来的结果。3d
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格式。code
FOR XML PATH的变通对象
更多的,FOR XML PATH子句是支持传递参数的,即FOR XML PATH(schema),这样的话在查询的时候就会将行标签<row>替换为<schema>,要注意的是schema必须是字符串。blog
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>,能不能更改/去除列标签呢?答案是能够的,能够经过给列起别名的方式来更改/除列标签。要注意的是这里的别名也必须是字符串。class
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函数。
"一个姑娘不会由于你专注痴情就喜欢你,只会由于你优秀而喜欢你。"