XQuery基于两个变量进行分组

时间:2011-01-18 12:53:48

标签: xml xquery

我有像这样的xml

<?xml version="1.0"?>
 <xmldb>
 <centers>
    <center id="0000100001" status="unsynced">
    <meetingdate>2011-01-13</meetingdate>
    <cname>Center1</cname>
    <cfe empid="1001">FE1</cfe>
    <groups>
        <group id="0000100002">
        <name>Group11</name>
         <members>
            <member id="0000100002">
                <fname>member111</fname>
                <lname>ln111</lname>
                    <loandetails>
                    <loan>
                        <productname>IGL1</productname>
                        <loanacctnum>0010000000001</loanacctnum>
                        <instnum>23</instnum>
                        <disbAmount>8000</disbAmount>
                        <disbDate>12/06/2010</disbDate>
                        <prdue>250</prdue>
                        <indue>25</indue>
                        <loanbalancePrincipal>2500</loanbalancePrincipal>
                        <loanbalanceIntrest>250</loanbalanceIntrest>
                        <amountpaid>0</amountpaid>
                        <attn>A</attn>
                    </loan>
                    <loan>
                        <productname>EDU</productname>
                        <loanacctnum>0010000000001</loanacctnum>
                        <instnum>23</instnum>
                        <disbAmount>2000</disbAmount>
                        <disbDate>12/06/2010</disbDate>
                        <prdue>110</prdue>
                        <indue>25</indue>
                        <loanbalancePrincipal>2500</loanbalancePrincipal>
                        <loanbalanceIntrest>250</loanbalanceIntrest>
                        <amountpaid>0</amountpaid>
                     </loan>
                    </loandetails>
            </member>
            <member id="0000100002">
                <fname>member111</fname>
                <lname>ln111</lname>
                    <loandetails>
                    <loan>
                        <productname>IGL1</productname>
                        <loanacctnum>0010000000001</loanacctnum>
                        <instnum>23</instnum>
                        <disbAmount>8000</disbAmount>
                        <disbDate>12/06/2010</disbDate>
                        <prdue>250</prdue>
                        <indue>25</indue>
                        <loanbalancePrincipal>2500</loanbalancePrincipal>
                        <loanbalanceIntrest>250</loanbalanceIntrest>
                        <amountpaid>0</amountpaid>
                    </loan> 
                    </loandetails>
            </member>
            <member id="0000100002">
                <fname>member112</fname>
                <lname>ln111</lname>
                    <loandetails>
                    <loan>
                        <productname>IGL1</productname>

                        <loanacctnum>0010000000001</loanacctnum>
                        <instnum>23</instnum>
                        <disbAmount>8000</disbAmount>
                        <disbDate>12/06/2010</disbDate>
                        <prdue>250</prdue>
                        <indue>25</indue>
                        <loanbalancePrincipal>2500</loanbalancePrincipal>
                        <loanbalanceIntrest>250</loanbalanceIntrest>
                        <amountpaid>0</amountpaid>
                    </loan> 
                    </loandetails>
            </member>
            <member id="0000100003">
                <fname>member113</fname>
                <lname>ln111</lname>
                    <loandetails>
                        <loan>
                        <productname>IGL1</productname>
                        <loanacctnum>0010000000001</loanacctnum>
                        <instnum>23</instnum>
                        <disbAmount>8000</disbAmount>
                        <disbDate>12/06/2010</disbDate>
                        <prdue>250</prdue>
                        <indue>25</indue>
                        <loanbalancePrincipal>2500</loanbalancePrincipal>
                        <loanbalanceIntrest>250</loanbalanceIntrest>
                        <amountpaid>0</amountpaid>
                        </loan>
                    </loandetails>
            </member>
        </members>  
        </group>
        <group id="0000100003">
        <name>Group12</name>
        <members>
            <member id="0000100003">
                <fname>member113</fname>
                <lname>ln111</lname>
                    <loandetails>
                        <loan>
                        <productname>IGL1</productname>

                        <loanacctnum>0010000000001</loanacctnum>
                        <instnum>23</instnum>
                        <disbAmount>8000</disbAmount>
                        <disbDate>12/06/2010</disbDate>
                        <prdue>250</prdue>
                        <indue>25</indue>
                        <loanbalancePrincipal>2500</loanbalancePrincipal>
                        <loanbalanceIntrest>250</loanbalanceIntrest>
                        <amountpaid>0</amountpaid>
                        </loan>
                    </loandetails>
            </member>
        </members>  
        </group>
    </groups>   
    </center>
  </centers>
 </xmldb>

需要根据centeris和会议日期汇总数据

所以我查询谎言

let $allItems := /xmldb/centers/center
for $d in distinct-values($allItems/@id)
for $n in distinct-values($allItems/meetingdate/text())
let $items := $allItems[@id = $d and meetingdate/text() = $n]
order by $items
return if (exists($items))
then <center id="{$d}" >
<date>{$n}</date>
<totaldue>{sum($items/groups/group/members/member/loandetails/loan/prdue)}</totaldue>
</center>
else ( )

回收像这样的数据

<center id="0000100003">
  <date>2011-01-11</date>
  <totaldue>610</totaldue>
</center>
<center id="0000100001">
  <date>2011-01-13</date>
  <totaldue>1360</totaldue>
</center>
<center id="0000100002">
  <date>2011-01-13</date>
  <totaldue>610</totaldue>
</center>

但我需要这种格式的数据

  <date value=2011-01-11>
     <center id="0000100003">
        <totaldue>610</totaldue>
     </center>
  </date>
  <date value=2011-01-13>
     <center id="0000100001">
        <totaldue>1360</totaldue>
     </center>
     <center id="0000100002">
        <totaldue>610</totaldue>
     </center>
  </date>

1 个答案:

答案 0 :(得分:0)

尝试:

    let $allItems := /xmldb/centers/center
    for $date in distinct-values($allItems/meetingdate)
    return
      <date value="{$date}"> {  
        let $dateItems := $allItems[meetingdate = $date]
        for $id in distinct-values($dateItems/@id) 
        return <center id="{$id}" >
                  <totaldue>
                    {sum($dateItems[@id=$id]/groups/group/members/member/loandetails/loan/prdue)}
                  </totaldue>
               </center>
      }</date>

顺便说一下,不需要那个/ text() - 最好使用元素的字符串值而不是找到它的文本节点,因为可能会有一些注释妨碍它。

我没有尝试对它进行排序,但是如果你需要的话,可以很容易地添加“按日期排序”或“按$ id排序”。

我认为来自SQL背景的人们倾向于尝试在一个大型多路FLWOR连接中执行所有操作。通常,XQuery的输出是分层的而不是表格式的,并且通常对输出中的每个层次结构都有一个FLWOR表达式(即一个return子句)。根据我的经验,在单个FLWOR表达式中有多个“for”子句是非常不寻常的。