I need to aggregate some sub-tag values into a Oracle SQL column.
Let’s say the XML structure is something like this:
<Product>
[..other tags..]
<Attributes>
<Statements Id="1" Name="Statement 0">
<Statement Id="4">Subtype 1</Statement>
</Statements>
<Statements Id="3" Name="Statement 1">
<Statement Id="4">Subtype 4</Statement>
<Statement Id="5">Subtype 5</Statement>
<Statement Id="15">Subtype 15</Statement>
</Statements>
<Statements Id="16" Name="Statement 2">
<Statement Id="4">Subtype 4</Statement>
<Statement Id="5">Subtype 5</Statement>
<Statement Id="10">Subtype 10</Statement>
</Statements>
</Attributes>
</Product>
My Product table in SQL should be populated with something like this:
Statement_2 with entry Subtype4,Subtype5,Subtype10…
etc..
I actually tryed to use some query like the following:
SELECT
b.id,
LISTAGG(x2.statement_1, ',') WITHIN GROUP (ORDER BY NULL) AS statement 1,
LISTAGG(y2.statement_2, ',') WITHIN GROUP (ORDER BY NULL) AS statement_2
FROM
TABLE_WHERE_XML_RESIDES b
CROSS JOIN
XMLTABLE('/root_path/Statements[@Id="3"]'
PASSING XMLTYPE(b.XML_DOCUMENT)
COLUMNS statement1_list XMLTYPE PATH 'Statement') x
CROSS JOIN
XMLTABLE('/Statement'
PASSING x.statement1_list
COLUMNS statement_name_1 VARCHAR2(100) PATH 'text()') x2
CROSS JOIN
XMLTABLE('/root_path/Statements[@Id="16"]'
PASSING XMLTYPE(b.XML_DOCUMENT)
COLUMNS statement1_list XMLTYPE PATH 'Statement') y
CROSS JOIN
XMLTABLE('/Statement'
PASSING x.statement2_list
COLUMNS statement_name_1 VARCHAR2(4000) PATH 'text()') y2
GROUP BY
b.id;
In this way the aggregation kinda of works, but for many the query will be not performant I guess. And main problem is, due to the join mechanisms subsequent statements values (i.e. statements 2) would be duplicated for N times (which correspond to the N entries already retreived for the column in statement1.
Sorry it’s really hard to explain this.. I’m open to discuss any suggestion / consideration!
Thanks.