在 XQuery 处理器 1.0 中,在日期值相同的地方添加值

Add the value where ever date value is same, In XQuery processor 1.0

要求:

<a>
   <main>
      <key>soa</key>
      <valuedate>34,2015-03-07</valuedate>
   </main>
   <main>
      <key>sob</key>
      <valuedate>34,2015-03-03</valuedate>
   </main>
   <main>
      <key>soa</key>
      <valuedate>3,2015-03-07</valuedate>
   </main>
   <main>
      <key>soa</key>
      <valuedate>6,2015-03-07</valuedate>
   </main>
   <main>
      <key>gros</key>
      <valuedate>4,2015-04-03</valuedate>
   </main>
</a>

我想要的结果:关键元素是 soa 并且日期相同(2015-03-07)然后应该添加值(34+3+6)

 <b>
   <res>
      <key>soa</key>
      <value>43</value>
      <date>2015-03-07</date>
   </res>
   <res>
      <key>sob</key>
      <value>34</value>
      <date>2015-03-03</date>
   </res>
   <res>
      <key>gros</key>
      <value>4</value>
      <date>2015-04-03</date>
   </res>
</b>

谁能告诉我如何做到这一点..?
最终响应,元素 <key> 也应显示其值以及我们仅对值为 "soa"

<key> 元素添加的值

这是使用两个 group by 条件的绝妙示例。因此,假设您的 XQuery 处理器处理 XQuery 3.0(其中引入了 group by),您可以执行以下操作:

for $main in /main
let $key := $main/key
let $number := xs:int(tokenize($main/valuedate, ',')[1])
let $date := tokenize($main/valuedate, ',')[2]
group by $key, $date
return <res>{sum($number)},{$date}</res>

它将首先按键分组,然后按日期分组,并使用聚合函数sum()相应地计算总和。

xquery version "1.0";

let $doc := <a>
   <main>
      <key>soa</key>
      <valuedate>34,2015-03-07</valuedate>
   </main>
   <main>
      <key>sob</key>
      <valuedate>34,2015-03-03</valuedate>
   </main>
   <main>
      <key>soa</key>
      <valuedate>3,2015-03-07</valuedate>
   </main>
   <main>
      <key>soa</key>
      <valuedate>6,2015-03-07</valuedate>
   </main>
   <main>
      <key>gros</key>
      <valuedate>4,2015-04-03</valuedate>
   </main>
</a>

(: split the values :)
let $recs := for $rec in $doc/main
  let $parts := fn:tokenize($rec/valuedate, ',')
  return <rec><count>{$parts[1]}</count><date>{$parts[2]}</date></rec>

return 
<b>
{
  for $res in 
    for $date in fn:distinct-values($recs/date/text())
      return <res>{fn:concat(fn:sum($recs[./date eq $date]/count), ',' , $date)}</res>
    order by xs:integer(fn:tokenize($res, ',')[1]) descending
    return $res
}
</b>

或者另一种处理方式(更难阅读,但移动部分更少)

return
<b>
  {
  for $date in fn:distinct-values(for $dates in $doc/main/valuedate/text()
        return fn:tokenize($dates, ',')[2])
      let $sum := fn:sum(for $num in $doc/main[fn:contains(./valuedate, $date)]/valuedate/text()
          return xs:decimal(fn:tokenize($num, ',')[1])
          )
      order by $sum descending
      return <res>{fn:concat($sum, ',' , $date)}</res>
   }
</b>