2012-05-18 3 views
2

Я использую XQuery для выполнения добавления. Ниже приводится структура XML сохраняется в базе данных:Сумма, использующая XQuery

<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> 

Я хочу, чтобы получить ниже выхода с помощью XQuery: сумма суммы, имеющей одинаковый код. Обратите внимание: , - .. Мне нужно заменить , на . и выполнить арифметическую операцию.

<Total>    
      <1001> 100,2 </1001> 
      <1002> 11,0 </1002> 
    </Total> 
+1

Вам действительно нужны значения кода как имена узлов? Не могли бы вы рассмотреть другую структуру вашего выходного XML, где у вас есть код как значение узла или значение атрибута? –

+0

В выводе вы не можете иметь квалифицированные имена, начинающиеся с цифры. Они должны начинаться с буквы или подчеркивания. –

+0

Hi Mikael, Также можно использовать A1001. но мне нужны значения кода как имена узлов. – Puru

ответ

6

Если ваш процессор поддерживает XQuery XQuery 3.0, используйте group by заявление.

<Total> 
{ 
    for $i in //Event 
    let $code := $i/code 
    group by $code 
    return element {"code"} { attribute {"id"} {$code}, sum($i/Amount)} 
} 
</Total> 

Есть два отличия к XML-фрагментам в вашем вопросе: я изменил точку Seperator плавающей к точкам (что требуется, конечно, вы можете сделать это, используя некоторые XQuery операции со строками, тоже) и имена элементов могут не состоят только из цифр, посмотрите на element naming rules. Я решил вернуть код как id-атрибут вместо этого в моем примере.

+0

Hi Ranon, Я хочу заменить, на. и сделайте дополнение, не могли бы вы помочь мне в этом, я пытаюсь использовать функцию замены, но это дает мне ошибку «SQL16003N выражение типа данных» (item(), item() +) »не может использоваться, когда тип данных «item()» ожидается в контексте. Ошибка QName = err: XPTY0004. " – Puru

+0

Спасибо, что попробовали себя перед тем, как задать вопрос. :) Вы, вероятно, использовали 'replace (...)' в обратной линии. Заменить ожидает единственная строка, а не цепочка строк. Добавьте эту строку в let-statements: 'let $ amount: = number (replace ($ i/Amount,", ",". "))'. Это заменяет двоеточие точкой и отбрасывает число. в 'sum (...)', sum над '$ amount'. –

+0

Вы можете попробовать отредактированную версию решения в прямом эфире по адресу http://www.zorba-xquery.com/html/demo#4yAN48cPJqRgjJvmSlBOzdEe0hk= Кажется, что все нормально. – wcandillon

3

Это даст вам данные в виде набора результатов.

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 
2

Следующий код будет вычислять итоговые значения и вывода результата в виде XML, но не в вашем выводе (который является недействительным):

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') 

где @x является переменной XML, содержащий данные.