Transform table data to XML












0















I have data like this:



        ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT PAID_AMOUNT RECEIVED   ENTERED   
---------- ---------- ---------- ------------- --------------- ----------- ---------- ----------
9331779 2017-08-11 11 606.42 127.59 2017-07-17 2017-07-18
9331779 2017-08-11 11 606.42 446.81 2017-08-16 2017-08-17
9331779 2017-08-11 11 606.42 32.02 2017-09-15 2017-09-18
9331782 2017-11-11 11 606.42 95.57 2017-11-15 2017-11-16
9331782 2017-11-11 11 606.42 446.81 2017-12-15 2017-12-18
9331782 2017-11-11 11 606.42 64.04 2018-01-03 2018-01-04




I want to transform this into XML data, looking like:



 <payment-list>
<payment>
<kind>11</kind>
<due>2017-08-11</due>
<amount>null/0</amount>
<waiting>606.42</waiting>
<related-payment-list>
<related-payment>
<received>2017-07-17</received>
<entered>2017-07-18</entered>
<amount>127.59</amount>
</related-payment>
<related-payment>
<received>2017-08-16</received>
<entered>2017-08-17</entered>
<amount>446.81</amount>
</related-payment>
<related-payment>...
</related-payment-list>
</payment>
<payment>
<kind>11</kind>
<due>2017-11-11</due>
<amount>null/0</amount>
<waiting>606.42</waiting>
<related-payment-list>
<related-payment>
<received>2017-11-15</received>
<entered>2017-11-16</entered>
<amount>95.57</amount>
</related-payment>
<related-payment>
<received>2017-12-15</received>
<entered>2017-12-18</entered>
<amount>446.81</amount>
</related-payment>
<related-payment>...
</related-payment-list>
</payment>
<payment-list>


Can this be done in single query? I have an idea/way to do it in loop, but maybe someone has other idea, using XMLAgg etc.










share|improve this question





























    0















    I have data like this:



            ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT PAID_AMOUNT RECEIVED   ENTERED   
    ---------- ---------- ---------- ------------- --------------- ----------- ---------- ----------
    9331779 2017-08-11 11 606.42 127.59 2017-07-17 2017-07-18
    9331779 2017-08-11 11 606.42 446.81 2017-08-16 2017-08-17
    9331779 2017-08-11 11 606.42 32.02 2017-09-15 2017-09-18
    9331782 2017-11-11 11 606.42 95.57 2017-11-15 2017-11-16
    9331782 2017-11-11 11 606.42 446.81 2017-12-15 2017-12-18
    9331782 2017-11-11 11 606.42 64.04 2018-01-03 2018-01-04




    I want to transform this into XML data, looking like:



     <payment-list>
    <payment>
    <kind>11</kind>
    <due>2017-08-11</due>
    <amount>null/0</amount>
    <waiting>606.42</waiting>
    <related-payment-list>
    <related-payment>
    <received>2017-07-17</received>
    <entered>2017-07-18</entered>
    <amount>127.59</amount>
    </related-payment>
    <related-payment>
    <received>2017-08-16</received>
    <entered>2017-08-17</entered>
    <amount>446.81</amount>
    </related-payment>
    <related-payment>...
    </related-payment-list>
    </payment>
    <payment>
    <kind>11</kind>
    <due>2017-11-11</due>
    <amount>null/0</amount>
    <waiting>606.42</waiting>
    <related-payment-list>
    <related-payment>
    <received>2017-11-15</received>
    <entered>2017-11-16</entered>
    <amount>95.57</amount>
    </related-payment>
    <related-payment>
    <received>2017-12-15</received>
    <entered>2017-12-18</entered>
    <amount>446.81</amount>
    </related-payment>
    <related-payment>...
    </related-payment-list>
    </payment>
    <payment-list>


    Can this be done in single query? I have an idea/way to do it in loop, but maybe someone has other idea, using XMLAgg etc.










    share|improve this question



























      0












      0








      0








      I have data like this:



              ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT PAID_AMOUNT RECEIVED   ENTERED   
      ---------- ---------- ---------- ------------- --------------- ----------- ---------- ----------
      9331779 2017-08-11 11 606.42 127.59 2017-07-17 2017-07-18
      9331779 2017-08-11 11 606.42 446.81 2017-08-16 2017-08-17
      9331779 2017-08-11 11 606.42 32.02 2017-09-15 2017-09-18
      9331782 2017-11-11 11 606.42 95.57 2017-11-15 2017-11-16
      9331782 2017-11-11 11 606.42 446.81 2017-12-15 2017-12-18
      9331782 2017-11-11 11 606.42 64.04 2018-01-03 2018-01-04




      I want to transform this into XML data, looking like:



       <payment-list>
      <payment>
      <kind>11</kind>
      <due>2017-08-11</due>
      <amount>null/0</amount>
      <waiting>606.42</waiting>
      <related-payment-list>
      <related-payment>
      <received>2017-07-17</received>
      <entered>2017-07-18</entered>
      <amount>127.59</amount>
      </related-payment>
      <related-payment>
      <received>2017-08-16</received>
      <entered>2017-08-17</entered>
      <amount>446.81</amount>
      </related-payment>
      <related-payment>...
      </related-payment-list>
      </payment>
      <payment>
      <kind>11</kind>
      <due>2017-11-11</due>
      <amount>null/0</amount>
      <waiting>606.42</waiting>
      <related-payment-list>
      <related-payment>
      <received>2017-11-15</received>
      <entered>2017-11-16</entered>
      <amount>95.57</amount>
      </related-payment>
      <related-payment>
      <received>2017-12-15</received>
      <entered>2017-12-18</entered>
      <amount>446.81</amount>
      </related-payment>
      <related-payment>...
      </related-payment-list>
      </payment>
      <payment-list>


      Can this be done in single query? I have an idea/way to do it in loop, but maybe someone has other idea, using XMLAgg etc.










      share|improve this question
















      I have data like this:



              ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT PAID_AMOUNT RECEIVED   ENTERED   
      ---------- ---------- ---------- ------------- --------------- ----------- ---------- ----------
      9331779 2017-08-11 11 606.42 127.59 2017-07-17 2017-07-18
      9331779 2017-08-11 11 606.42 446.81 2017-08-16 2017-08-17
      9331779 2017-08-11 11 606.42 32.02 2017-09-15 2017-09-18
      9331782 2017-11-11 11 606.42 95.57 2017-11-15 2017-11-16
      9331782 2017-11-11 11 606.42 446.81 2017-12-15 2017-12-18
      9331782 2017-11-11 11 606.42 64.04 2018-01-03 2018-01-04




      I want to transform this into XML data, looking like:



       <payment-list>
      <payment>
      <kind>11</kind>
      <due>2017-08-11</due>
      <amount>null/0</amount>
      <waiting>606.42</waiting>
      <related-payment-list>
      <related-payment>
      <received>2017-07-17</received>
      <entered>2017-07-18</entered>
      <amount>127.59</amount>
      </related-payment>
      <related-payment>
      <received>2017-08-16</received>
      <entered>2017-08-17</entered>
      <amount>446.81</amount>
      </related-payment>
      <related-payment>...
      </related-payment-list>
      </payment>
      <payment>
      <kind>11</kind>
      <due>2017-11-11</due>
      <amount>null/0</amount>
      <waiting>606.42</waiting>
      <related-payment-list>
      <related-payment>
      <received>2017-11-15</received>
      <entered>2017-11-16</entered>
      <amount>95.57</amount>
      </related-payment>
      <related-payment>
      <received>2017-12-15</received>
      <entered>2017-12-18</entered>
      <amount>446.81</amount>
      </related-payment>
      <related-payment>...
      </related-payment-list>
      </payment>
      <payment-list>


      Can this be done in single query? I have an idea/way to do it in loop, but maybe someone has other idea, using XMLAgg etc.







      sql xml oracle






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 2 at 12:01









      Alex Poole

      134k6108182




      134k6108182










      asked Jan 2 at 10:54









      q4za4q4za4

      31918




      31918
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Nesting XMLAgg() calls is a bit tricky, but you could do this in two stages; first get each ID/due/kind/amount with a list of related payments:



          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(xmlelement("related-payment",
          xmlforest(received as "received", entered as "entered", paid_amount as "amount")))
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount;


          which with your sample data gives (with the XMl fragment serialized for readability):



                  ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT XMLSERIALIZE(CONTENTXMLAGG(XMLELEMENT("RELATED-PAYMENT",XMLFOREST(RECEIVEDAS"REC
          ---------- ---------- ---------- ------------- --------------- --------------------------------------------------------------------------------
          9331779 2017-08-11 11 606.42 <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          ...


          and then use that as an inline view for the second level of aggregation:



          select
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          ) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          Demo with your sample data as a CTE, and again adding serialization for readability:



          -- CTE for sample data
          with your_table (id, due_date, kind, unpaid_amount, required_amount, paid_amount, received, entered) as (
          select 9331779, date '2017-08-11', 11, null, 606.42, 127.59, date '2017-07-17', date '2017-07-18' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 446.81, date '2017-08-16', date '2017-08-17' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 32.02, date '2017-09-15', date '2017-09-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 95.57, date '2017-11-15', date '2017-11-16' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 446.81, date '2017-12-15', date '2017-12-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 64.04, date '2018-01-03', date '2018-01-04' from dual
          )
          -- actual query
          select xmlserialize(document
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          )
          indent size=2) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          which gets:



          RESULT                                                                          
          --------------------------------------------------------------------------------
          <payment-list>
          <payment>
          <kind>11</kind>
          <due>2017-08-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          <entered>2017-09-18</entered>
          <amount>32.02</amount>
          </related-payment>
          <related-payment>
          <received>2017-08-16</received>
          <entered>2017-08-17</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          <payment>
          <kind>11</kind>
          <due>2017-11-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-11-15</received>
          <entered>2017-11-16</entered>
          <amount>95.57</amount>
          </related-payment>
          <related-payment>
          <received>2018-01-03</received>
          <entered>2018-01-04</entered>
          <amount>64.04</amount>
          </related-payment>
          <related-payment>
          <received>2017-12-15</received>
          <entered>2017-12-18</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          </payment-list>





          share|improve this answer
























          • Smooth as... Thanks!

            – q4za4
            Jan 2 at 12:50











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005042%2ftransform-table-data-to-xml%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Nesting XMLAgg() calls is a bit tricky, but you could do this in two stages; first get each ID/due/kind/amount with a list of related payments:



          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(xmlelement("related-payment",
          xmlforest(received as "received", entered as "entered", paid_amount as "amount")))
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount;


          which with your sample data gives (with the XMl fragment serialized for readability):



                  ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT XMLSERIALIZE(CONTENTXMLAGG(XMLELEMENT("RELATED-PAYMENT",XMLFOREST(RECEIVEDAS"REC
          ---------- ---------- ---------- ------------- --------------- --------------------------------------------------------------------------------
          9331779 2017-08-11 11 606.42 <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          ...


          and then use that as an inline view for the second level of aggregation:



          select
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          ) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          Demo with your sample data as a CTE, and again adding serialization for readability:



          -- CTE for sample data
          with your_table (id, due_date, kind, unpaid_amount, required_amount, paid_amount, received, entered) as (
          select 9331779, date '2017-08-11', 11, null, 606.42, 127.59, date '2017-07-17', date '2017-07-18' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 446.81, date '2017-08-16', date '2017-08-17' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 32.02, date '2017-09-15', date '2017-09-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 95.57, date '2017-11-15', date '2017-11-16' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 446.81, date '2017-12-15', date '2017-12-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 64.04, date '2018-01-03', date '2018-01-04' from dual
          )
          -- actual query
          select xmlserialize(document
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          )
          indent size=2) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          which gets:



          RESULT                                                                          
          --------------------------------------------------------------------------------
          <payment-list>
          <payment>
          <kind>11</kind>
          <due>2017-08-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          <entered>2017-09-18</entered>
          <amount>32.02</amount>
          </related-payment>
          <related-payment>
          <received>2017-08-16</received>
          <entered>2017-08-17</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          <payment>
          <kind>11</kind>
          <due>2017-11-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-11-15</received>
          <entered>2017-11-16</entered>
          <amount>95.57</amount>
          </related-payment>
          <related-payment>
          <received>2018-01-03</received>
          <entered>2018-01-04</entered>
          <amount>64.04</amount>
          </related-payment>
          <related-payment>
          <received>2017-12-15</received>
          <entered>2017-12-18</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          </payment-list>





          share|improve this answer
























          • Smooth as... Thanks!

            – q4za4
            Jan 2 at 12:50
















          1














          Nesting XMLAgg() calls is a bit tricky, but you could do this in two stages; first get each ID/due/kind/amount with a list of related payments:



          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(xmlelement("related-payment",
          xmlforest(received as "received", entered as "entered", paid_amount as "amount")))
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount;


          which with your sample data gives (with the XMl fragment serialized for readability):



                  ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT XMLSERIALIZE(CONTENTXMLAGG(XMLELEMENT("RELATED-PAYMENT",XMLFOREST(RECEIVEDAS"REC
          ---------- ---------- ---------- ------------- --------------- --------------------------------------------------------------------------------
          9331779 2017-08-11 11 606.42 <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          ...


          and then use that as an inline view for the second level of aggregation:



          select
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          ) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          Demo with your sample data as a CTE, and again adding serialization for readability:



          -- CTE for sample data
          with your_table (id, due_date, kind, unpaid_amount, required_amount, paid_amount, received, entered) as (
          select 9331779, date '2017-08-11', 11, null, 606.42, 127.59, date '2017-07-17', date '2017-07-18' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 446.81, date '2017-08-16', date '2017-08-17' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 32.02, date '2017-09-15', date '2017-09-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 95.57, date '2017-11-15', date '2017-11-16' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 446.81, date '2017-12-15', date '2017-12-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 64.04, date '2018-01-03', date '2018-01-04' from dual
          )
          -- actual query
          select xmlserialize(document
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          )
          indent size=2) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          which gets:



          RESULT                                                                          
          --------------------------------------------------------------------------------
          <payment-list>
          <payment>
          <kind>11</kind>
          <due>2017-08-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          <entered>2017-09-18</entered>
          <amount>32.02</amount>
          </related-payment>
          <related-payment>
          <received>2017-08-16</received>
          <entered>2017-08-17</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          <payment>
          <kind>11</kind>
          <due>2017-11-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-11-15</received>
          <entered>2017-11-16</entered>
          <amount>95.57</amount>
          </related-payment>
          <related-payment>
          <received>2018-01-03</received>
          <entered>2018-01-04</entered>
          <amount>64.04</amount>
          </related-payment>
          <related-payment>
          <received>2017-12-15</received>
          <entered>2017-12-18</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          </payment-list>





          share|improve this answer
























          • Smooth as... Thanks!

            – q4za4
            Jan 2 at 12:50














          1












          1








          1







          Nesting XMLAgg() calls is a bit tricky, but you could do this in two stages; first get each ID/due/kind/amount with a list of related payments:



          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(xmlelement("related-payment",
          xmlforest(received as "received", entered as "entered", paid_amount as "amount")))
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount;


          which with your sample data gives (with the XMl fragment serialized for readability):



                  ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT XMLSERIALIZE(CONTENTXMLAGG(XMLELEMENT("RELATED-PAYMENT",XMLFOREST(RECEIVEDAS"REC
          ---------- ---------- ---------- ------------- --------------- --------------------------------------------------------------------------------
          9331779 2017-08-11 11 606.42 <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          ...


          and then use that as an inline view for the second level of aggregation:



          select
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          ) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          Demo with your sample data as a CTE, and again adding serialization for readability:



          -- CTE for sample data
          with your_table (id, due_date, kind, unpaid_amount, required_amount, paid_amount, received, entered) as (
          select 9331779, date '2017-08-11', 11, null, 606.42, 127.59, date '2017-07-17', date '2017-07-18' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 446.81, date '2017-08-16', date '2017-08-17' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 32.02, date '2017-09-15', date '2017-09-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 95.57, date '2017-11-15', date '2017-11-16' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 446.81, date '2017-12-15', date '2017-12-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 64.04, date '2018-01-03', date '2018-01-04' from dual
          )
          -- actual query
          select xmlserialize(document
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          )
          indent size=2) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          which gets:



          RESULT                                                                          
          --------------------------------------------------------------------------------
          <payment-list>
          <payment>
          <kind>11</kind>
          <due>2017-08-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          <entered>2017-09-18</entered>
          <amount>32.02</amount>
          </related-payment>
          <related-payment>
          <received>2017-08-16</received>
          <entered>2017-08-17</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          <payment>
          <kind>11</kind>
          <due>2017-11-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-11-15</received>
          <entered>2017-11-16</entered>
          <amount>95.57</amount>
          </related-payment>
          <related-payment>
          <received>2018-01-03</received>
          <entered>2018-01-04</entered>
          <amount>64.04</amount>
          </related-payment>
          <related-payment>
          <received>2017-12-15</received>
          <entered>2017-12-18</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          </payment-list>





          share|improve this answer













          Nesting XMLAgg() calls is a bit tricky, but you could do this in two stages; first get each ID/due/kind/amount with a list of related payments:



          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(xmlelement("related-payment",
          xmlforest(received as "received", entered as "entered", paid_amount as "amount")))
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount;


          which with your sample data gives (with the XMl fragment serialized for readability):



                  ID DUE_DATE         KIND UNPAID_AMOUNT REQUIRED_AMOUNT XMLSERIALIZE(CONTENTXMLAGG(XMLELEMENT("RELATED-PAYMENT",XMLFOREST(RECEIVEDAS"REC
          ---------- ---------- ---------- ------------- --------------- --------------------------------------------------------------------------------
          9331779 2017-08-11 11 606.42 <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          ...


          and then use that as an inline view for the second level of aggregation:



          select
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          ) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          Demo with your sample data as a CTE, and again adding serialization for readability:



          -- CTE for sample data
          with your_table (id, due_date, kind, unpaid_amount, required_amount, paid_amount, received, entered) as (
          select 9331779, date '2017-08-11', 11, null, 606.42, 127.59, date '2017-07-17', date '2017-07-18' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 446.81, date '2017-08-16', date '2017-08-17' from dual
          union all select 9331779, date '2017-08-11', 11, null, 606.42, 32.02, date '2017-09-15', date '2017-09-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 95.57, date '2017-11-15', date '2017-11-16' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 446.81, date '2017-12-15', date '2017-12-18' from dual
          union all select 9331782, date '2017-11-11', 11, null, 606.42, 64.04, date '2018-01-03', date '2018-01-04' from dual
          )
          -- actual query
          select xmlserialize(document
          xmlelement("payment-list",
          xmlagg(
          xmlelement("payment",
          xmlforest(kind as "kind",
          to_char(due_date, 'YYYY-MM-DD') as "due",
          nvl(unpaid_amount, 0) as "amount",
          nvl(required_amount, 0) as "waiting",
          related_payments as "related-payment-list"
          )
          )
          )
          )
          indent size=2) as result
          from (
          select id, due_date, kind, unpaid_amount, required_amount,
          xmlagg(
          xmlelement("related-payment",
          xmlforest(received as "received",
          entered as "entered",
          paid_amount as "amount"
          )
          )
          ) as related_payments
          from your_table
          group by id, due_date, kind, unpaid_amount, required_amount
          );


          which gets:



          RESULT                                                                          
          --------------------------------------------------------------------------------
          <payment-list>
          <payment>
          <kind>11</kind>
          <due>2017-08-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-07-17</received>
          <entered>2017-07-18</entered>
          <amount>127.59</amount>
          </related-payment>
          <related-payment>
          <received>2017-09-15</received>
          <entered>2017-09-18</entered>
          <amount>32.02</amount>
          </related-payment>
          <related-payment>
          <received>2017-08-16</received>
          <entered>2017-08-17</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          <payment>
          <kind>11</kind>
          <due>2017-11-11</due>
          <amount>0</amount>
          <waiting>606.42</waiting>
          <related-payment-list>
          <related-payment>
          <received>2017-11-15</received>
          <entered>2017-11-16</entered>
          <amount>95.57</amount>
          </related-payment>
          <related-payment>
          <received>2018-01-03</received>
          <entered>2018-01-04</entered>
          <amount>64.04</amount>
          </related-payment>
          <related-payment>
          <received>2017-12-15</received>
          <entered>2017-12-18</entered>
          <amount>446.81</amount>
          </related-payment>
          </related-payment-list>
          </payment>
          </payment-list>






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 2 at 11:57









          Alex PooleAlex Poole

          134k6108182




          134k6108182













          • Smooth as... Thanks!

            – q4za4
            Jan 2 at 12:50



















          • Smooth as... Thanks!

            – q4za4
            Jan 2 at 12:50

















          Smooth as... Thanks!

          – q4za4
          Jan 2 at 12:50





          Smooth as... Thanks!

          – q4za4
          Jan 2 at 12:50




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005042%2ftransform-table-data-to-xml%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith