带有order by子句问题的Oracle Union

时间:2017-03-13 12:32:27

标签: sql oracle

实际查询如下所示:

select to_char(first_name||'('||substr(last_name,0,1)||')') 
from employees 
order by first_name
union
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;

单独两个查询都可以工作但是当我添加Union来组合结果时,我在sql developer中得到以下错误:

  

ORA-00933:SQL命令未正确结束   00933. 00000 - “SQL命令未正确结束”   *原因:
  *行动:   行错误:2列:1

我想先显示第一个查询中的所有记录,然后依次显示第二个查询中的所有记录,每个记录按上面给出的顺序排序。

3 个答案:

答案 0 :(得分:2)

这样做的方法通常是提供一个标识“联合组”的列,其中应该出现一行:

select name 
from (
  select first_name||'('||substr(last_name,0,1)||')' as name, 
         1 as sort_order, 
         0 as counter, 
         0 as job_id
  from employees 
  union all 
  select 'There are total '||count(job_id)||' '||lower(job_id)||'s', 
         2, 
         count(job_id), 
         job_id
  from employees
  group by job_id 
) t
order by sort_order, counter, job_id, name;

由于您还希望使用不同的列对第二部分内的行进行排序,因此需要为其创建虚拟列,以便可以对整体结果应用正确的order by

我还会从您的查询中移除无用的to_char()来电。

如果job_id实际上是varchar列(lower(job_id)似乎表示),那么您需要将0 as job_id替换为某个字符常量。它的价值并不重要。

在线示例:http://rextester.com/ZUPQ98121

答案 1 :(得分:1)

它应该是工作

di

答案 2 :(得分:1)

潜在的障碍是SQL数据集本质上是无序的。只要您使用UNION两个数据集,就会失去先前存在的订购保证。

您通常可以使用以下结构,但仍然无法保证......

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
;

在实践中,你经常可以通过这种结构获得你想要的东西。

括号确保在UNION ALL之前完成排序,数据库引擎PROBABLY不会接受订购。

但是可能。保证结果顺序的唯一方法是在外部查询上放置ORDER BY。像下面这样的东西通常工作得很好......

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
;

我在手机上,所以可能会有错别字,但情绪就在那里......

使用ROWNUM或ROW_NUMBER()在数据集中生成额外字段。然后结合他们。然后按新字段排序。