Oracle联合默认排序很奇怪

Dec*_*ard 0 oracle order-by union

如您所知,union删除重复的行。我认为它从后者中删除,但事实并非如此。

我发现如果没有order by子句,Oracle 会按第一列对合并的数据集进行排序并删除重复项。

select 4,5,6 from dual
union 
select 1,2,3 from dual
union 
select 4,5,6 from dual
Run Code Online (Sandbox Code Playgroud)

结果:

1   2   3
4   5   6
Run Code Online (Sandbox Code Playgroud)

而我期望:

4   5   6
1   2   3
Run Code Online (Sandbox Code Playgroud)

我在这方面失败了很多次,并使问题变得简单,就像上面的例子一样。

如何在没有 的情况下保持联合序列order by

在我的真实案例中,第一个select是完全匹配(=)结果,第二个是部分匹配(like)结果。

例如,如果我搜索罗马人

全场比赛结果:罗马,部分比赛结果:香气

当然,完整的比赛结果应该是第一位的。正如我所说,它似乎order byunion结果的第一列。

但是,如您所见:

select 'roma' from dual -- result comes out anyway..
union select 'aroma' from dual;
Run Code Online (Sandbox Code Playgroud)

结果:

aroma
roma
Run Code Online (Sandbox Code Playgroud)

按字母顺序,aroma排在roma 之前,它排在最前面。

也许我应该尝试union all删除重复项?

Phi*_*lᵀᴹ 5

简单的答案是......

order在任何结果集中强制执行 an ,而不仅仅是您的特定情况,您必须使用order by子句。

Oracle文档阐明它明确:

使用 ORDER BY 子句对语句返回的行进行排序。如果没有 order_by_clause,则无法保证多次执行的同一查询会以相同的顺序检索行。


And*_*y M 5

正如已经多次提到的那样,如果不使用 ORDER BY 子句显式指定该顺序,就不能期望行按特定顺序排列。

对于您的问题中描述的问题,您实际上根本不需要 UNION。仅使用 LIKE 条件来覆盖完全匹配和部分匹配:

WHERE
  name LIKE '%roma%'
Run Code Online (Sandbox Code Playgroud)

然后使用条件表达式根据匹配是完全匹配还是部分匹配对行进行排名,例如使用 DECODE 函数:

ORDER BY
  DECODE(name, 'roma', 1, 2) ASC
Run Code Online (Sandbox Code Playgroud)

或 CASE 表达式,对于另一个:

ORDER BY
  CASE name WHEN 'roma' THEN 1 ELSE 2 END ASC
Run Code Online (Sandbox Code Playgroud)