2012-05-18 54 views
2

我正在使用XQuery執行附加操作。以下是保存在數據庫中的XML的結構:我想通過使用XQuery得到以下輸出使用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> 

:具有相同的代碼量的總和。請注意0​​是.。我需要用.代替,並執行算術運算。

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

你真的需要代碼值作爲節點名嗎?您可以考慮將輸出XML的另一個結構作爲節點值或屬性值嗎? –

+0

在您的輸出中,您不能擁有以數字開頭的限定名稱。它們應以字母或下劃線開頭。 –

+0

嗨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片段:我改變了浮點分隔符來分(這是必須的,當然你可以做到這一點使用一些XQuery的字符串操作,太)和元素名稱可能不是隻包含數字,請查看element naming rules。我決定將代碼作爲id屬性返回,而不是在我的示例中。

+0

嗨Ranon, 我想替換,通過。並做了補充,請你幫我在這裏,我試圖使用替換函數,但它給我錯誤「SQL16003N數據類型的表達式」(項目(),項目()+)「不能使用時在上下文中預期數據類型「item()」。錯誤QName = err:XPTY0004。「 – Puru

+0

謝謝您在詢問之前嘗試自己。 :)你可能在return-line中使用了'replace(...)'。替換期望一個單一的字符串,而不是一堆字符串。將這一行添加到let語句中:'let $ amount:= number(replace($ i/Amount,「,」,「。」))''。這用一個點替換冒號並且轉換爲數字。在'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變量。