基于不同属性类型的XML值总和

时间:2018-09-25 15:34:49

标签: sql-server xml xpath xquery xquery-sql

我正尝试从以下示例XML中提取成人,儿童和婴儿的数量:

  • 成人= AgeType 3
  • 孩子= AgeType 2
  • 婴儿= AgeType 1

,然后计数指定该年龄类型的数量。正确的结果是:

  • 35名成人
  • 5个孩子
  • 2名婴儿

下面的代码返回正确的结果,但是我想避免将cross apply输入到<Customer>标签中(因为每天有数亿)。

declare @a table(a xml)
insert into @a  
select '<Customers>
        <Customer AgeType="3" Count="10" />    
        <Customer AgeType="3" Count="20" />
        <Customer AgeType="3" Count="5" />       
        <Customer AgeType="2" Count="5" />
        <Customer AgeType="1" Count="2" />
        </Customers>'

select  
    sum(case when b.cust = 3 then b.cust*b.count_cust end)/3 as adt
    ,sum(case when b.cust = 2 then b.cust*b.count_cust end)/2 as chd
    ,sum(case when b.cust = 1 then b.cust*b.count_cust end)/1 as inf
from   (
select c.value('(@AgeType)','int') As cust
,c.value('(@Count)','int') As count_cust
from @a cross apply a.nodes('Customers/Customer') as t(c)
) as b

有人能找到其他更有效率的逻辑吗?我当时在考虑像下面这样在count标签上使用sum<Customer>,但是我无法获得正确的结果。

 a.value('count(Customers/Customer/@AgeType[.=3])','int') As adt
,a.value('count(Customers/Customer/@AgeType[.=2])','int') As chd
,a.value('count(Customers/Customer/@AgeType[.=1])','int') As inf

1 个答案:

答案 0 :(得分:1)

从更改XPath

count(Customers/Customer/@AgeType[.=3])

sum(Customers/Customer[@AgeType = 3]/@Count)

总结所有成人(@AgeType = 3)Customer @Count属性值。

对于其他年龄类型,请遵循相同的模式。