一行变多行

http://msdn.microsoft.com/zh-cn/library/ms188282.aspx这个网址里介绍了nodes、value函数,大家可以从这里详细的学习。下面说说我的心得。

最近遇到个问题,一个字段中含有分号,要按照分号分成多行,从网上查了一下,现把我这两天学习的总结一下,希望可以帮助大家。

表格PkTable如下:

id txt
1 aa;bb

 

想转化成如下进行统计:

id txt
1 aa
1 bb

 

 

查询方法如下:

select

a.id,b.txt

from

(select id,txt=convert(xml,'<root><v>'+replace(txt,';','</v><v>')+'</v></root>') from PkTable)a

outer apply

(select txt=C.v.value('.','nvarchar(100)') from a.txt.nodes('/root/v')C(v))b

我解释下这个sql中用到的一些语法:

(1)replace函数,是将';'替换为了'</v><v>',又经'+'连接,经convert类型转化,表a的数据如下:

id txt
1 <root><v>aa</v><v>bb</v></root>

 

(2)在b表中,a.txt指的是a表的txt列,nodes函数的作用是根据参数中的字符串(标签)将xml转化为关系数据集,即转化为行 ,C(v)是别名,C为表明,v为列名。

通过一下语句进行查询C表的数据:

select C.v.query('.') txt
  from PkTable
 outer apply txt.nodes('/root/v')as C(v)

查询结果如下:

txt
<v>aa</v>
<v>bb</v>

 

 

(3)C.v.value('.','nvarchar(100)'),C是表,v是列,value函数是读取标签之间的值,对于这个列子,读取的为<v>和</v>中间的值;

value的第一个参数是一个字符串文字,从 XML 实例内部检索数据。 XQuery 必须最多返回一个值。 否则,将返回错误;

value的第二个参数是指将查询结果转化为何种类型的数据。

此处,'.'表示当前目录,即<v>目录,另外'..'表示上级目录,'/'表示根目录,这个跟Linux是一样的。

通过以下语句查询b表:

select b.txt

from

(select id,txt=convert(xml,'<root><v>'+replace(txt,';','</v><v>')+'</v></root>') from PkTable)a

outer apply

(select txt=C.v.value('.','nvarchar(100)') from a.txt.nodes('/root/v')C(v))b

b表的数据如下:

txt
aa
bb

 

 

(4)最后就是outer apply了,他是先定好a表的列,然后取b表的列插入。对于这个函数,大家可以从网上查询,我也不是太了解。

最后的查询结果为:

 id txt
 1   aa
 1 bb

 

posted @ 2014-09-16 16:11  虎虎小猫咪  阅读(611)  评论(0编辑  收藏  举报