SQL Server中有提供一个FOR XML PATH的子句(须知sql2005及以上版本才能用),用来将查询结果行输出成XML格式,我们可以通过这个语法做一些变通实现一些特定的功能,比如说行转列。
FOR XML PATH
子句会将查询结果行输出为XML
格式
SELECT [no], name
FROM dog FOR XML PATH;
<row>
<no>15701no>
<name>校花name>
row>
<row>
<no>15703no>
<name>小邋遢name>
row>
<row>
<no>15702no>
<name>校草name>
row>
<row>
<no>15704no>
<name>三毛name>
row>
限制条件
在FOR XML PATH子句前添加WHERE子句限定条件范围来限定获取信息的范围(也可以使用自连接限定范围)。
FOR XML PATH子句可支持传递参数的,即
FOR XML PATH(schema)
,在查询的时候就会将行标签替换为
,要注意的是schema必须是字符串。
SELECT [no], name
FROM dog FOR XML PATH('dog');
结果
<dog>
<no>15701no>
<name>校花name>
dog>
<dog>
<no>15703no>
<name>小邋遢name>
dog>
<dog>
<no>15702no>
<name>校草name>
dog>
<dog>
<no>15704no>
<name>三毛name>
dog>
利用XML的特点,即空标签不会存在的特定,将行标签
去掉。
SELECT [no], name
FROM dog FOR XML PATH('');
结果
<no>15701no>
<name>校花name>
<no>15703no>
<name>小邋遢name>
<no>15702no>
<name>校草name>
<no>15704no>
<name>三毛name>
给列起别名的方式来更改或去掉除列标签
SELECT [no] AS lable, name AS nickname
FROM dog FOR XML PATH('');
结果
<lable>15701lable>
<nickname>校花nickname>
<lable>15703lable>
<nickname>小邋遢nickname>
<lable>15702lable>
<nickname>校草nickname>
<lable>15704lable>
<nickname>三毛nickname>
注:列标签不能将别名定义为空字符串,否则会报如下错误
> [42000] [Microsoft][SQL Server Native Client 10.0][SQL Server]缺少对象或列名,或者对象或列名为空。对于 SELECT INTO 语句,请确保每列均具有名称。对于其他语句,请查找空的别名。不允许使用定义为 "" 或 [] 的别名。请将别名更改为有效名称。 (1038)
方法:不起别名,且给字段加上空字符串(加空字符串为了保持原值不变,如有需要亦可加其他字符串)
SELECT [no] + '', name + ''
FROM dog FOR XML PATH('');
结果
15701校花15703小邋遢15702校草15704三毛
根据上述的FOR XML PATH的行列变化,我们可以来实现行转列。
SELECT STUFF((SELECT ';' + name FROM dog FOR XML PATH ('')), 1, 1, '') AS name;
结果
校花;小邋遢;校草;三毛
STUFF
函数(推荐)
STUFF(character_expression, start, length, character_expression)
或REPLACE
函数去除分号
REPLACE(string_expression, string_pattern, string_replacement)
在MYSQL中行转列使用GROUP_CONCAT
-- 分割符默认逗号
GROUP_CONCAT([DISTINCT] 列名 [ORDER BY 列名 DESC/ASC] [SEPARATOR 字符串])
关于行列转换函数:SQL SERVER还提供了另外的行转列的PRIVOT
函数和列转行的UNPRIVOT
函数。