我有这样的数据:
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
我想将其转换为XML数据,如下所示:
<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>
可以在单个查询中完成吗?我有一个想法/方法可以循环执行,但也许有人使用XMLAgg等有其他想法。
答案 0 :(得分:1)
嵌套XMLAgg()
调用有点棘手,但是您可以分两个阶段进行;首先获取每个ID /到期日/种类/金额以及相关付款清单:
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;
与您的示例数据一起给出的(为便于阅读而对XMl片段进行了序列化):
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>
...
,然后将其用作第二层聚合的内联视图:
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
);
将示例数据作为CTE进行演示,然后再次添加序列化以提高可读性:
-- 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
);
得到:
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>