Reputation: 47
I'm using XQuery to perform addition. Following is the structure of XML saved in database:
<Events>
<Event>
<id>1</id>
<code>1001</code>
<Amount>50,1</Amount>
</Event>
<Event>
<id>1</id>
<code>1002</code>
<Amount>5,5</Amount>
</Event>
<Event>
<id>1</id>
<code>1001</code>
<Amount>50,1</Amount>
</Event>
<Event>
<id>1</id>
<code>1002</code>
<Amount>5,5</Amount>
</Event>
</Events>
I want to get below output by using XQuery: the sum of amount having same code. Please note ,
is .
. I need to replace ,
by .
and the perform arithmetic operation.
<Total>
<1001> 100,2 </1001>
<1002> 11,0 </1002>
</Total>
Upvotes: 2
Views: 6532
Reputation: 38732
If your XQuery processor supports XQuery 3.0, use the group by
statement.
<Total>
{
for $i in //Event
let $code := $i/code
group by $code
return element {"code"} { attribute {"id"} {$code}, sum($i/Amount)}
}
</Total>
There are two differences to the XML snippets in your question: I changed the floating point seperator to points (which is required, of course you could do this using some XQuery string operations, too) and element names may not consist of numbers only, have a look at the element naming rules. I decided to return the code as id-attribute instead in my example.
Upvotes: 6
Reputation: 2782
The following code will calculate the totals and output the result as XML, but not in your output (which is invalid):
SELECT Code AS 'Code', SUM(Value) AS 'Total'
FROM (
SELECT
CONVERT(DECIMAL(9,2), REPLACE(c.value('Amount[1]', 'VARCHAR(10)'), ',', '.')) AS Value
, c.value('code[1]', 'INT') AS Code
FROM @x.nodes('//Event') AS t(c)
) t
GROUP BY Code
FOR XML PATH('Total'), ROOT('Totals')
where @x
is a XML variable containing your data.
Upvotes: 2
Reputation: 139010
This will get you the data as a result set.
declare @X xml
set @X =
'<Events>
<Event>
<id>1</id>
<code>1001</code>
<Amount>50,1</Amount>
</Event>
<Event>
<id>1</id>
<code>1002</code>
<Amount>5,5</Amount>
</Event>
<Event>
<id>1</id>
<code>1001</code>
<Amount>50,1</Amount>
</Event>
<Event>
<id>1</id>
<code>1002</code>
<Amount>5,5</Amount>
</Event>
</Events>'
select T.code,
sum(Amount) as Amount
from
(
select T.X.value('code[1]', 'int') as code,
cast(replace(T.X.value('Amount[1]', 'varchar(13)'), ',', '.') as float) as Amount
from @X.nodes('Events/Event') as T(X)
) as T
group by T.code
Upvotes: 3