首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XQUERY中的排序与合并

XQUERY中的排序与合并
EN

Stack Overflow用户
提问于 2016-04-14 11:16:27
回答 1查看 81关注 0票数 0

我很难根据需要应用的一些合并规则对一组XML进行排序。我是在XQuery 1.0中这样做的,并且一直在使用不同的值函数,但是我发现很难把我所需要的所有记录联系起来。

我试图应用的逻辑是

  • 对于频率和支付者以及缴款类型相同的情况,每个组合都需要出现一次。
  • 其中一个事件是具有最近日期的组合的实例。
  • 如果在同一记录上出现了与同一日期、最近日期、付款人和频率相同的详细信息,则需要将它们合并,以便为该频率显示的金额和该特定日期的付款人是在该日期支付的总额。
  • 如果列表中存在比记录上更多的内容,则需要合并详细信息,以获得具有最近日期的组合的实例。

任何帮助都会很感激的。

代码语言:javascript
复制
     <transaction_history>
        <contribution_transaction contribution_type="Type A" currency="GBP">
           <date>2015-12-31</date>
           <payer>Employer</payer>
           <amount>5042.38</amount>
           <frequency>Quarterly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type A" currency="GBP">
           <date>2015-12-31</date>
           <payer>Employer</payer>
           <amount>4676.94</amount>
           <frequency>Monthly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type B" currency="GBP">
           <date>2015-09-08</date>
           <payer>Employer</payer>
           <amount>4317.52</amount>
           <frequency>Monthly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type A" currency="GBP">
           <date>2015-12-31</date>
           <payer>Employer</payer>
           <amount>9393.11</amount>
           <frequency>Quarterly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type A" currency="GBP">
           <date>2015-10-02</date>
           <payer>Employee</payer>
           <amount>3944.49</amount>
           <frequency>Monthly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type B" currency="GBP">
           <date>2015-12-31</date>
           <payer>Employee</payer>
           <amount>3675.85</amount>
           <frequency>Monthly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type B" currency="GBP">
           <date>2015-10-02</date>
           <payer>Employee</payer>
           <amount>3385.69</amount>
           <frequency>Monthly</frequency>
        </contribution_transaction>
        <contribution_transaction contribution_type="Type A" currency="GBP">
           <date>2015-12-31</date>
           <payer>Employee</payer>
           <amount>7369.64</amount>
           <frequency>Monthly</frequency>
        </contribution_transaction>
     </transaction_history>

在…的例子中

代码语言:javascript
复制
<contribution_transaction contribution_type="Type A" currency="GBP">
       <date>2015-12-31</date>
       <payer>Employer</payer>
       <amount>5042.38</amount>
       <frequency>Quarterly</frequency>
    </contribution_transaction>
<contribution_transaction contribution_type="Type A" currency="GBP">
       <date>2015-12-31</date>
       <payer>Employer</payer>
       <amount>5042.38</amount>
       <frequency>Quarterly</frequency>
    </contribution_transaction>

将导致:

代码语言:javascript
复制
 <contribution_transaction contribution_type="Type A" currency="GBP">
       <date>2015-12-31</date>
       <payer>Employer</payer>
       <amount>10084.76</amount>
       <frequency>Quarterly</frequency>
    </contribution_transaction>
EN

回答 1

Stack Overflow用户

发布于 2016-04-14 12:05:10

您可以一个接一个地进行两个嵌套分组:

代码语言:javascript
复制
for $frequency in distinct-values(//frequency)
let $contrib := //contribution_transaction[frequency = $frequency]
for $payer in distinct-values($contrib/payer)
let $res := $contrib[payer = $payer]
let $min-date := min($res/date/xs:date(.))
return <result frequency="{$frequency}" payer="{$payer}">{
  (: do something clever with the relevant transactions here :)
  $res[xs:date(date) = $min-date]
}</result>

由于您的日期格式与字典排序顺序是正确排序的,所以您也可以直接比较字符串:

代码语言:javascript
复制
for $frequency in distinct-values(//frequency)
let $contrib := //contribution_transaction[frequency = $frequency]
for $payer in distinct-values($contrib/payer)
let $res := $contrib[payer = $payer]
let $min-date := min($res/date/string())
return <result frequency="{$frequency}" payer="{$payer}">{
  (: do something clever with the relevant transactions here :)
  $res[date = $min-date]
}</result>

由于您的处理器似乎只支持node()的参数作为fn:min(...)的参数,所以可以使用以下快速替换:

代码语言:javascript
复制
declare function local:min($seq) {
  local:min((), $seq)
};

declare function local:min($min, $seq) {
  if(empty($seq)) then $min
  else (
    let $first := $seq[1], $rest := $seq[position() > 1]
    return (
      if($min < $first) then local:min($min, $rest)
      else local:min($first, $rest)
    )
  )
};

(: example usage :)
local:min(('B', 'A', 'b'))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36621454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档