T-SQL XML Query,如何将匹配节点分成单独的行?第二部分

时间:2012-05-05 11:12:18

标签: sql-server xml tsql xquery

这个问题跟进了这个很好的答案:T-SQL XML Query, how to seperate matching nodes into individual rows? 如果值为:

,该怎么办?
   <child>
    <name>Fred</name>
    <sname>Flintstone</name>
   </child>
   <child>
    <name>Bill</name>
    <sname>Gates</name>
   </child>

我希望输出如下:

Fred
Flintstone
Bill
Gates

甚至更好,这个:

name: Fred
sname: Flintstone
name: Bill
sname: Gates

(全部在一栏中)

- &gt;由于我无法在接下来的3个小时内回答我自己的问题,我将按照stackoverflow的建议编辑我的问题。这是我对自己问题的回答:

我已经明白了! :-)所以我不得不分享我自己的解决方案。这是:

SELECT
  distinct childs.value('fn:local-name(.)', 'nvarchar(50)') + '=' + childs.value('(text())[1]', 'varchar(50)') as Children
FROM  
  #t CROSS APPLY
  data.nodes('//parent/child/*') AS Children(childs)  

感谢任何人查看我的问题!

2 个答案:

答案 0 :(得分:2)

declare @XML xml
set @XML = 
'<child>
  <name>Fred</name>
  <sname>Flintstone</sname>
 </child>
 <child>
   <name>Bill</name>
   <sname>Gates</sname>
 </child>'

select N.value('concat(local-name(.),": ",.)', 'varchar(max)')
from @XML.nodes('/child/*') as T(N)

结果:

name: Fred 
sname: Flintstone 
name: Bill 
sname: Gates 

<强>更新
使用表格并保证order by

declare @XML xml
set @XML = 
'<child>
  <name>Fred</name>
  <sname>Flintstone</sname>
 </child>
 <child>
   <name>Bill</name>
   <sname>Gates</sname>
 </child>'

declare @T table (ID int identity primary key, XMLColumn xml)
insert into @T values(@XML)
insert into @T values(@XML)

select ID,
       Names
from
  (
    select ID,
           N.value('concat(local-name(.),": ",.)', 'varchar(max)') as Names,
           row_number() over(partition by ID order by T.N) as rn
    from @T
      cross apply XMLColumn.nodes('/child/*') as T(N)
  ) T
order by ID, rn 

答案 1 :(得分:1)

这为每个<child>输出提供了两列:

DECLARE @input XML = '<child>
    <name>Fred</name>
    <sname>Flintstone</sname>
   </child>
   <child>
    <name>Bill</name>
    <sname>Gates</sname>
   </child>'

SELECT
    'name: ' + child.value('(name)[1]', 'varchar(50)'),
    'sname: ' + child.value('(sname)[1]', 'varchar(50)')
FROM @input.nodes('/child') AS nodes(child)

输出是:

name: Fred  |  sname: Flintstone
name: Bill  |  sname: Gates

如果您只想要一列,则可以使用此列:

SELECT
    'name: ' + child.value('(name)[1]', 'varchar(50)')
FROM @input.nodes('/child') AS nodes(child)

UNION

SELECT
    'sname: ' + child.value('(sname)[1]', 'varchar(50)')
FROM @input.nodes('/child') AS nodes(child)

这会给你这个输出:

(No column name)
name: Bill
name: Fred
sname: Flintstone
sname: Gates