连接 XML 属性 SQL 服务器
Concatenate XML Attributes SQL Server
我有一个 XML 数据集,它定义了 Customers 的列表以及客户购买的所有 Products
<Info>
<Customer CustomerId="1">
<Product Name="A" Cost="20" />
<Product Name="C" Cost="30" />
</Customer>
<Customer CustomerId="2">
<Product Name="A" Cost="23" />
<Product Name="B" Cost="46" />
</Customer>
<Customer CustomerId="3">
<Product Name="B" Cost="32" />
<Product Name="C" Cost="64" />
</Customer>
</Info>
我想像这样在单独的查询中列出客户及其产品
Customer
Products
1
A , C
2
A , B
3
B , C
刚接触 SQL 服务器中的 XQuery 我正在努力寻找解决方案。在过去的几天里,我想出了一个看起来像这样的查询
declare @xml xml;
...
select
Info.Customer.value('@CustomerID[1]', 'int') as CustomerID,
Info.Customer.query('./*') as Products
from
@xml.nodes('info/Customer') Info(Customer);
产生以下结果
Customer
Products
1
<Product Name="A", Cost="20" />, <Product Name="C", Cost="30" />
2
<Product Name="A", Cost="23" />, <Product Name="B", Cost="46" />
3
<Product Name="B", Cost="32" />, <Product Name="C", Cost="64" />
对于熟悉使用 FOR XML
使用以下模式连接行的那些人,我想澄清一下 不是 我的意思要求。
SELECT
CustomerId,
(
SELECT Name + ' $' + Cost
FROM Product
WHERE Product.CustomerId = Customer.CustomerId
FOR XML PATH(''), TYPE
)
FROM Customer
我用来生成 <Info>...</Info>
数据集的查询只用了一小部分时间,并且拥有我需要的所有数据,我只是想知道是否有任何方法可以连接同样的方式?
正如@lptr 在评论中指出的那样,您可以使用以下任一解决方案
declare @xml xml = N'<Info>
<Customer CustomerId="1">
<Product Name="A" Cost="20" />
<Product Name="C" Cost="30" />
</Customer>
<Customer CustomerId="2">
<Product Name="A" Cost="23" />
<Product Name="B" Cost="46" />
</Customer>
<Customer CustomerId="3">
<Product Name="B" Cost="32" />
<Product Name="C" Cost="64" />
</Customer>
</Info>';
select
i.c.value('@CustomerId', 'int'),
stuff(
i.c.query('
for $p in Product
return text{concat(", ", $p/@Name, " $", $p/@Cost)}
').value('text()[1]', 'varchar(max)'), 1, 2,''),
i.c.query('
for $p in Product
return text{concat($p/@Name, " $", $p/@Cost, if ($p is Product[last()]) then "" else ", ")}
')
from @xml.nodes('Info/Customer') as i(c);
我有一个 XML 数据集,它定义了 Customers 的列表以及客户购买的所有 Products
<Info>
<Customer CustomerId="1">
<Product Name="A" Cost="20" />
<Product Name="C" Cost="30" />
</Customer>
<Customer CustomerId="2">
<Product Name="A" Cost="23" />
<Product Name="B" Cost="46" />
</Customer>
<Customer CustomerId="3">
<Product Name="B" Cost="32" />
<Product Name="C" Cost="64" />
</Customer>
</Info>
我想像这样在单独的查询中列出客户及其产品
Customer | Products |
---|---|
1 | A , C |
2 | A , B |
3 | B , C |
刚接触 SQL 服务器中的 XQuery 我正在努力寻找解决方案。在过去的几天里,我想出了一个看起来像这样的查询
declare @xml xml;
...
select
Info.Customer.value('@CustomerID[1]', 'int') as CustomerID,
Info.Customer.query('./*') as Products
from
@xml.nodes('info/Customer') Info(Customer);
产生以下结果
Customer | Products |
---|---|
1 | <Product Name="A", Cost="20" />, <Product Name="C", Cost="30" /> |
2 | <Product Name="A", Cost="23" />, <Product Name="B", Cost="46" /> |
3 | <Product Name="B", Cost="32" />, <Product Name="C", Cost="64" /> |
对于熟悉使用 FOR XML
使用以下模式连接行的那些人,我想澄清一下 不是 我的意思要求。
SELECT
CustomerId,
(
SELECT Name + ' $' + Cost
FROM Product
WHERE Product.CustomerId = Customer.CustomerId
FOR XML PATH(''), TYPE
)
FROM Customer
我用来生成 <Info>...</Info>
数据集的查询只用了一小部分时间,并且拥有我需要的所有数据,我只是想知道是否有任何方法可以连接同样的方式?
正如@lptr 在评论中指出的那样,您可以使用以下任一解决方案
declare @xml xml = N'<Info>
<Customer CustomerId="1">
<Product Name="A" Cost="20" />
<Product Name="C" Cost="30" />
</Customer>
<Customer CustomerId="2">
<Product Name="A" Cost="23" />
<Product Name="B" Cost="46" />
</Customer>
<Customer CustomerId="3">
<Product Name="B" Cost="32" />
<Product Name="C" Cost="64" />
</Customer>
</Info>';
select
i.c.value('@CustomerId', 'int'),
stuff(
i.c.query('
for $p in Product
return text{concat(", ", $p/@Name, " $", $p/@Cost)}
').value('text()[1]', 'varchar(max)'), 1, 2,''),
i.c.query('
for $p in Product
return text{concat($p/@Name, " $", $p/@Cost, if ($p is Product[last()]) then "" else ", ")}
')
from @xml.nodes('Info/Customer') as i(c);