XQuery для группировки на основе двух переменных - PullRequest
0 голосов
/ 18 января 2011

У меня есть 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>

И необходимо агрегировать данные на основе центра и даты собрания

Так что я спрашиваю ложь это

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 голосов
/ 18 января 2011

Попробуйте:

    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 () - лучше использовать строковое значение элемента, чем находить его текстовые узлы, потому что могут быть комментарии, которые мешают.

Я не пробовал сортировать его, но достаточно просто добавить "order by $ date" или "order by $ id", если это то, что вам нужно.

Я думаю, что у людей с опытом работы в SQL есть тенденция делать все в одном большом многопользовательском соединении FLWOR. Обычно выходные данные XQuery являются иерархическими, а не табличными, и у вас обычно есть одно выражение FLWOR (то есть одно возвращаемое предложение) для каждого уровня иерархии в выходных данных. По моему опыту, иметь более одного предложения for в одном выражении FLWOR очень необычно.

...