Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle SQL Order By with XML and Union ALL

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

enter image description here

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

like image 963
Ichigo Avatar asked Jan 27 '26 12:01

Ichigo


1 Answers

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>
like image 172
Marmite Bomber Avatar answered Jan 29 '26 00:01

Marmite Bomber



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!