联合所有:合并排序(无子查询)

Union all: Order by coalesce (without subquery)

我有两个要联合在一起的表:WORKORDER_1 和 WORKORDER_2。

--fake tables in WITH clause

with workorders_1 as (
select 'WO1' as wonum,      null as parent from dual
union all
select 'WO100' as wonum, 'WO1' as parent from dual
union all
select 'WO100' as wonum, 'WO1' as parent from dual
),

workorders_2 as (
select 'WO200' as wonum, 'WO2' as parent from dual
union all
select 'WO200' as wonum, 'WO2' as parent from dual
union all
select 'WO2' as wonum, null as parent from dual
)

select * from workorders_1
union all
select * from workorders_2

WONUM    PARENT
-----    ------
WO1         
WO100    WO1   
WO100    WO1   
WO200    WO2   
WO200    WO2   
WO2  

我想按合并的父 ID 对联合表进行排序:


结果如下所示:

WONUM    PARENT    [order by/coalesce]
-----    ------    ----------
WO1                [WO1]
WO100    WO1       [WO1]
WO100    WO1       [WO1]

WO2                [WO2]
WO200    WO2       [WO2]
WO200    WO2       [WO2]

我更愿意在不将查询包装为子查询的情况下进行排序。

是否可以通过使用类似合并的逻辑来排序——而不使用子查询?

您可以在 order by 子句中使用 coalesce()。对于这样的表达式,Oracle 要求您将 union 查询包装在子查询中:

select *
from (
    select * from workorders_1
    union all
    select * from workorders_2
) t
order by coalesce(parent, wonum), wonum

Demo on DB Fiddle

您的列名表明存在层次结构。如果是这种情况,那么您应该考虑以分层方式查询数据 https://docs.oracle.com/database/121/SQLRF/queries003.htm#SQLRF52332.

您可以在每个并集中使用查询连接。如果您从父行开始,默认排序将为您提供所需的内容:

with workorders_1 as (
select 'WO1' as wonum,      null as parent from dual
union all
select 'WO100' as wonum, 'WO1' as parent from dual
union all
select 'WO100' as wonum, 'WO1' as parent from dual
),
workorders_2 as (
select 'WO200' as wonum, 'WO2' as parent from dual
union all
select 'WO200' as wonum, 'WO2' as parent from dual
union all
select 'WO2' as wonum, null as parent from dual
)
select wonum, parent from workorders_1
connect by parent  = prior wonum
start with parent is null
union all
select wonum, parent from workorders_2
connect by parent  = prior wonum
start with parent is null

WONUM   PARENT
WO1   
WO100   WO1
WO100   WO1
WO2  
WO200   WO2
WO200   WO2