I wrote a select statement like this:
Select
xmlagg(xmlelement( "Species",
xmlelement("Type",Type),
xmlelement("Name",Name),
xmlforest(case when Tail is not null then Tail else null end "Trait")))
From Table_Animals
Order By Name;
This is my input
The query runs fine, but when I added an UNION ALL like so:
Select
xmlagg(xmlelement( "Species",
xmlelement("Type",Type),
xmlelement("Name",Name),
xmlforest(case when Tail is not null then Tail else null end "Trait")))
From Table_Animals
UNION ALL
Select
xmlagg(xmlelement( "Species",
xmlelement("Type",Type),
xmlelement("Name",Name),
xmlforest(case when Teeth is not null then Teeth else null end "Trait")))
From Table_Animals
Where Prey is not null
Order By Name;
I got the error : ORA-00904: "Name": invalid identifier
How do I use Order By correctly in the above example?
My desired output is:
<Species>
<Type>Bird<Type>
<Name>Eagle<Name>
<Species>
<Species>
<Type>Mammal<Type>
<Name>Fox<Name>
<Trait>Sharp<Trait>
<Species>
<Species>
<Type>Plant<Type>
<Name>Lettuce<Name>
<Species>
<Species>
<Type>Mammal<Type>
<Name>Rabbit<Name>
<Trait>Short<Trait>
<Species>
<Species>
<Type>Mammal<Type>
<Name>Rabbit<Name>
<Trait>Dull<Trait>
<Species>
<Species>
<Type>Amphibian<Type>
<Name>Snake<Name>
<Trait>Long<Trait>
<Species>
<Species>
<Type>Amphibian<Type>
<Name>Snake<Name>
<Trait>Sharp<Trait>
<Species>
Notice that Snake and Rabbit shows up twice in the output
You can order the result of XMLAgg using the order_by_clause
of XMLAgg.
In the first step perform a simple UNION ALL
(without XML) to duplicate the data as required.
Finaly use the order_by_clause
of XMLAgg
example data
create table Table_Animals as
select 'T1' type, 'dog' name, 'tai1' tail, 'Y' prey, 'tee1' teeth from dual union all
select 'T1' type, 'elephant' name, 'tai2' tail, 'Y' prey, 'tee2' teeth from dual union all
select 'T2' type, 'cat' name, 'tai3' tail, null prey, 'tee3' teeth from dual;
The query
with ua as (
select TYPE, NAME, TAIL, PREY, TEETH, Tail as trait from Table_Animals union all
select TYPE, NAME, TAIL, PREY, TEETH, Teeth as trait from Table_Animals where Prey is not null)
Select
xmlagg(xmlelement( "Animal",
xmlelement("Type",Type),
xmlelement("Name",Name),
xmlelement("Trait",Trait)) order by name) xml_col
From ua
;
note the definition of the column trait
in the subquery.
note the order by name near the xml_col
gives
<Animal>
<Type>T2
</Type>
<Name>cat
</Name>
<Trait>tai3
</Trait>
</Animal>
<Animal>
<Type>T1
</Type>
<Name>dog
</Name>
<Trait>tai1
</Trait>
</Animal>
<Animal>
<Type>T1
</Type>
<Name>dog
</Name>
<Trait>tee1
</Trait>
</Animal>
<Animal>
<Type>T1
</Type>
<Name>elephant
</Name>
<Trait>tai2
</Trait>
</Animal>
<Animal>
<Type>T1
</Type>
<Name>elephant
</Name>
<Trait>tee2
</Trait>
</Animal>