Xquery SUM после округления значения

Я хочу суммировать количество всех продуктов/продуктов/количества после округления значения.

Мой XML выглядит так:

<Products>
  <Product>
    <ExternalId>116511</ExternalId>
    <Price>2.99 </Price>
    <Quantity>1.500 </Quantity>
    <NetValue>4.08 </NetValue>
  </Product>
  <Product>
    <ExternalId>116510</ExternalId>
    <Price>2.99 </Price>
    <Quantity>1.500 </Quantity>
    <NetValue>4.08 </NetValue>
  </Product>
  <Product>
    <ExternalId>116512</ExternalId>
    <Price>1.99 </Price>
    <Quantity>10.000 </Quantity>
    <NetValue>18.09 </NetValue>
  </Product>
  <Product>
    <ExternalId>329245</ExternalId>
    <Price>59.99 </Price>
    <Quantity>1.000 </Quantity>
    <NetValue>54.53 </NetValue>
  </Product>
</Products> 

Приведенный выше XML хранится в x со столбцом данных.

Я пробовал использовать функции суммы и округления xQuery, но это только округляет и суммирует первый экземпляр Quantity (т.е. sum(round(1.5)) = 2):

SELECT Data.Value('(Products/Product/ExternalId/text()[1]', 'float') AS ExternalId,
x.Data.value('sum(round((/row/Products[1]/Product/Quantity)[1]))', 'float') Trn_Quantity
FROM x

person user2034250    schedule 08.02.2016    source источник
comment
Не уверен, что понимаю, что пытается сделать ваш запрос. Вам нужен первый ExternalId вместе с суммой всех количеств?   -  person Joachim Isaksson    schedule 08.02.2016


Ответы (2)


Вы можете попробовать использовать конструкцию цикла XQuery for, чтобы округлить отдельные Quantity и передать их sum(), примерно так:

SELECT 
    Data.Value('(Products/Product/ExternalId/text()[1]) AS ExternalId,
    x.Data.value('
        sum(
            for $quantity in /Products[1]/Product/Quantity
            return round($quantity)
        )
    ', 'float') Trn_Quantity
FROM x

Быстрый тест здесь: http://sqlfiddle.com/#!3/9eecb7/7351

person har07    schedule 08.02.2016
comment
Спасибо har07, это работает отлично. Не знал, что в xQuery можно использовать циклы. Ты узнаешь что-то новое каждый день. - person user2034250; 08.02.2016

Вы можете использовать CROSS APPLY, чтобы получить все узлы количества, а затем просто суммировать их. в обычном SQL;

SELECT SUM(ROUND(p.value('.', 'float'), 0)) AS Quantity
FROM mytable x
CROSS APPLY data.nodes('/Products/Product/Quantity') t(p)

... или, чтобы суммировать другие поля продукта, получить узлы продукта с перекрестным применением и суммировать подузлы по имени;

SELECT SUM(p.value('(./Price)[1]', 'float')) AS Price,
       SUM(ROUND(p.value('(./Quantity)[1]', 'float'), 0)) AS Quantity
FROM mytable x
CROSS APPLY data.nodes('/Products/Product') t(p)
person Joachim Isaksson    schedule 08.02.2016