The underlying obstacle is that a SQL dataset is inherently UNordered. As soon as you UNION two datasets you lose any guarantee of ordering previously present.
You can often get away with the following structure, but it is STILL not guaranteed...
SELECT * FROM ( ( select to_char(first_name||'('||substr(last_name,0,1)||')') from employees order by first_name ) Individuals UNION ALL ( select to_char('There are total '||count(job_id)||' '||lower(job_id)||'s') from employees group by job_id order by count(job_id),job_id ) Totals ) Combined ;
In practice you Often get what you want with this structure.
The brackets ensure the ordering is done before the UNION ALL and the database engine PROBABLY won't screw with the ordering.
But it MIGHT. The only way to Guarantee the order of the results is to put an ORDER BY on the outer query. Something like the following normally works fairly well...
SELECT rowdata FROM ( ( select 1 AS myset, rownum AS myrow, to_char(first_name||'('||substr(last_name,0,1)||')') AS rowdata from employees order by first_name ) Individuals UNION ALL ( select 2 AS myset, rownum AS myrow, to_char('There are total '||count(job_id)||' '||lower(job_id)||'s') from employees group by job_id order by count(job_id),job_id ) Totals ) Combined ORDER BY myset, myrow ;
I'm on my phone, so there may be typos, but the sentiment is there...
Use ROWNUM or ROW_NUMBER() to generate an extra field in your data sets. Then union them. Then order by your new field(s).
to_char()call does not make any sense.first_nameandlast_nameare already varchars so there is no need to convert them to a varchar usingto_char()