在XQuery中重复同级节点时求和值

在XQuery中重复同级节点时求和值,xquery,Xquery,我有一系列嵌套的节点,我正在尝试查找每个贷款中到期日节点的重复日期(仅考虑年和月),然后对其兄弟节点的值求和(金额)。 举个例子解释得更好 文件payments.xml: <loan> <id>1</id> <payments> <local_payment> <due_date>2012-11-28T08:00:00Z</due_date> <amount>

我有一系列嵌套的节点,我正在尝试查找每个
贷款中
到期日
节点的重复日期(仅考虑年和月),然后对其兄弟节点的值求和(
金额
)。 举个例子解释得更好

文件
payments.xml

<loan>
 <id>1</id>
 <payments>
    <local_payment>
        <due_date>2012-11-28T08:00:00Z</due_date>
        <amount>484</amount>
    </local_payment>
    <local_payment>
        <due_date>2012-12-05T08:00:00Z</due_date>
        <amount>450</amount>
    </local_payment>
    <local_payment>
        <due_date>2012-12-12T08:00:00Z</due_date>
        <amount>484</amount>
    </local_payment>
    <local_payment>
        <due_date>2012-01-19T08:00:00Z</due_date>
        <amount>450</amount>
    </local_payment>
    <local_payment>
        <due_date>2012-01-26T08:00:00Z</due_date>
        <amount>450</amount>
    </local_payment>
 </payments>
</loan>
<loan>
  <id>2</id>
  <payments>
    <local_payment>
        <due_date>2013-02-02T08:00:00Z</due_date>
        <amount>500</amount>
    </local_payment>
    <local_payment>
        <due_date>2013-02-09T08:00:00Z</due_date>
        <amount>500</amount>
    </local_payment>
    <local_payment>
        <due_date>2013-03-16T08:00:00Z</due_date>
        <amount>600</amount>
    </local_payment>
    <local_payment>
        <due_date>2013-04-23T08:00:00Z</due_date>
        <amount>650</amount>
    </local_payment>
  </payments>
</loan>

1.
2012-11-28 08:00:00Z
484
2012-12-05T08:00:00Z
450
2012-12-12T08:00:00Z
484
2012-01-19T08:00:00Z
450
2012-01-26T08:00:00Z
450
2.
2013-02-02T08:00:00Z
500
2013-02-09T08:00:00Z
500
2013-03-16T08:00:00Z
600
2013-04-23T08:00:00Z
650
我已经写了一个简单的函数,只提取年份和月份,但我不知道如何做其余的。
每个贷款的预期输出应该没有重复的日期,并且它们的金额相加。

这是的XQuery 3.0构造的一个很好的例子,因此我假设您的XQuery处理器支持3.0

您可以根据这样的年/月条件进行分组(有内置函数来获取dateTime的月份和年份,因此无需编写自己的函数)。然后可以使用
sum()
计算总和

但是,XQuery是一种查询语言,不用于更新现有数据,因此必须重新构建数据。由于您没有具体说明如何生成输出结构,所以我采用了自己的方法—根据需要进行调整

for $loan in /loan
return 
  <loan>
  { $loan/id }
  <payments>{
    for $payment in $loan/payments/local_payment
    let $year-month := month-from-dateTime($payment/due_date) || year-from-dateTime($payment/due_date)
    group by $year-month
    return <local_payment>
      { $payment/due_date }
      <amount>{ sum($payment/amount) }</amount>
    </local_payment>

  }</payments></loan>
用于$loan in/loan
返回
{$loan/id}
{
以美元贷款/付款/本地付款的形式支付美元
设$year-month:=从日期开始的月份($payment/due_date)|从日期开始的年份($payment/due_date)
按$year-month分组
返回
{$付款/到期日}
{金额(付款/金额)}
}

我刚刚回答了您的问题,但您的问题实际上需要改进。对于XML/Xquery问题,发布您的预期输出总是很有用的,因为目前还不清楚您到底想要什么(在我的回答中,“没有重复的日期”是什么意思,我仍然输出重复的日期…)。此外,如果你已经写了一些东西,请把它包括在你的问题中,即使它失败了——这只是为了表明你的努力。最后,但并非最不重要的一点:欢迎来到SO!非常感谢@dirkk的快速回复。对不起,下次我会按照你的提示提问。这是我需要的。这些数据将存储在输出文件中,然后我将使用它们与其他数据进行比较。谢谢,现在我知道了group by语句,为了只包含不同的日期,我将使用distinct values函数。我只检索月份和年份的函数是:
将函数local:year MOUNT($seq as node()*)声明为xs:string{for$I in$seq return substring($I,1,7)}我用它来只显示不同的日期:
。。。。。。返回{不同的值($payment/local:year-month(到期日))}{sum($payment/amount)}
是否正确,或者是否有其他方法?感谢您始终使用内置函数,而不是编写自己的函数。正如我所说的,XQuery中有内置函数用于从dateTime获取月份和年份,因此不要使用某些子字符串,只需使用它即可(查看
2012-12-31T17:00:00-07:00
)。特别是对于日期,这是相关的,因为日期计算非常困难。例如,有效的日期时间
2012-12-31T17:00:00-07:00
2013-01-01T00:00:00Z
实际上是相同的,但使用您的函数会有不同的年份和月份。