2015-12-17 124 views
2

我有很多的訂單像下面這樣:如何獲得XQuery中計算值的最大值?

<order id="1"> 
    <TargetPrice>100</TargetPrice> 
    <Qty>2</Qty> 
</order> 

我需要一個XQuery獲得與最高值的順序(其中value是TargetPrice *數量)

我怎樣才能做到這一點?

回答

3

按降序對訂單進行排序,並返回第一個元素。

(
    for $order in //order 
    let $value := $order/TargetPrice * $order/Qty 
    order by $value descending 
    return $order 
)[1] 
+0

這樣我就可以通過一個讓變量順序?太好了!謝謝! – gbalduzzi

+0

@Jens Erat如果有很多訂單的最高價值,答案是不正確的。 – Kachna

+1

的確,這也適用於@ MichaelKay的回答。 OP詢問了一個訂單,但。 –

2

您可能想要實現函數和操作符3.1規範的D.6.1中的函數。這比「排序並採取第一個」解決方案稍微長一點,但它可能更快(原則上它是流式的),並且代碼具有高度可重用性。

D.6.1例如:最高

的功能例如:最高回報具有用於提供的函數的最高值的項目。

XSLT實現

(SNIP)

XQuery實現

declare function eg:highest(
        $seq as item()* 
        $f as function(item()) as xs:anyAtomicType) 
        as item()* { 
    fn:fold-left(
     fn:tail($seq), fn:head($seq), 
     function($highestSoFar as item()*, $this as item()*) as item()* { 
     let $thisValue := $f($this) 
     let $highestValue := $f($highestSoFar[1]) 
     return 
      if ($thisValue gt $highestValue) 
      then $this 
      else if ($thisValue eq $highestValue) 
      then ($highestSoFar, $this) 
      else $highestSoFar 
     }) 
}; 

要找到薪水最高的員工,該函數可以被稱爲:

eg:highest(//employee, function($emp){$emp/salary}) 
1

另一個選項將使用simple map operator !並計算產品的TargetPrice * Qty物品的序列,然後選擇max()值,並在謂語使用:

let $maxVal := max(//order ! (TargetPrice * Qty)) 
return //order[(TargetPrice * Qty) eq $maxVal] 
+0

這會給你最高的價值V,但是你需要回過頭來找到價值爲V的訂單。 –

+0

是的,沒有引起足夠的重視。以爲他是在問價值,而不是價值最高的''。 –