查询具有多个子实体的XML

时间:2016-07-27 22:43:12

标签: sql xml sql-server-2008 tsql

我对如何在SQL Server 2008+中查询XML有基本的了解。基本。但是我正在努力从这个简单的XML中得到我想要的东西,而且今天下午我已经搜索了SO和网络很长一段时间并没有找到寻求帮助的神奇词汇。

鉴于此XML:

declare @xml xml =
'<?xml version="1.0" encoding="utf-8"?>
<Customers>
  <Customer id="12345" name="John Doe" addr1="123 Somewhere Ln" city="Riverside" state="CA">
    <Children>Jane</Children>
    <Children>John Jr.</Children>
    <Children>Susan</Children>
  </Customer>
</Customers>
<Customers>
  <Customer id="97531" name="Ben Franklin" addr1="456 Anywhere Dr" city="Albuquerque" state="NM">
    <Children>Andrew</Children>
    <Children>Adam</Children>
  </Customer>
</Customers>'

我可以运行此查询并获取ID和名称:

select cust.col.value('@id[1]','int') as id,
       cust.col.value('@name[1]','varchar(30)') as name
  from @xml.nodes('/Customers/Customer') as cust(col)

id     name
12345  John Doe
97531  Ben Franklin

然而,我接下来想要的是每个孩子的身份和姓名,而我无法弄清楚需要做什么。我想要这个:

id      child
12345   Jane
12345   John Jr.
12345   Susan
97531   Andrew
97531   Adam

请注意,我想要的是列式数据,而不是XML。

那么,什么是SELECT将从xml中获得那些结果?

谢谢!

2 个答案:

答案 0 :(得分:1)

根据您的查询,只需在CROSS APPLY元素上添加Children即可。现在,您可以从Customer以及Children元素中选择数据:

select cust.col.value('@id','int') as id,
       child.col.value('.','varchar(30)') as child
from @xml.nodes('/Customers/Customer') as cust(col)
    cross apply cust.col.nodes('Children') as child(col)

输出

id          child
----------- ------------------------------
12345       Jane
12345       John Jr.
12345       Susan
97531       Andrew
97531       Adam

请注意.用于引用当前元素上下文;并且,在XML中,同一个父元素中不能有2个同名的属性,因此不需要@id[1]中的索引器。

答案 1 :(得分:1)

你可以:

select cust.col.value('../@id','int') as id,
       cust.col.value('../@name','varchar(30)') as name,
       cust.col.value('.','varchar(30)') as child
  from @xml.nodes('/Customers/Customer/Children') as cust(col)

得到:

id      name            child
12345   John Doe        Jane
12345   John Doe        John Jr.
12345   John Doe        Susan
97531   Ben Franklin    Andrew
97531   Ben Franklin    Adam