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

时间:2015-11-09 06:12:22

标签: xml xquery

请求:

<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>也应该显示其值以及我们仅为<key>元素添加的值,其值为&#34; soa&#34;

2 个答案:

答案 0 :(得分:0)

这是使用两个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()相应地计算总和。

答案 1 :(得分:0)

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>