oracle使用order by排序null值如何处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle使用order by排序null值如何处理相关的知识,希望对你有一定的参考价值。

适用情况:oracle 对查询结果进行排序时,被排序的栏位存在null值,且要指定NULL值排在最前面或者最后面关键字:Nulls First;Nulls Last默认情况:null 默认为最大值(即:asc 升序<小-->大>,null值排在最后;desc 降序<大-->小>,null值排在最前面)指定:1.Oracle Order by支持的语法2.指定Nulls first 则表示null值的记录将排在最前(不管是asc 还是desc)3.指定Nulls last 则表示null值的记录将排在最后(不管是asc 还是desc)语法举例:(Table:Tab_A 有部分空值的栏位Col_A)select * from Tab_A order by Tab_A. Col_A (asc/desc) nulls first------>null 值排在最前面select * from Tab_A order by Tab_A. Col_A (asc/desc) nulls last ------>null 值排在最后面其他方法:在order by 的时候,用Nvl、NVL2 、Decode、case .....when....end;等函数对栏位的null值进行处理 参考技术A

适用情况:oracle 对查询结果进行排序时,被排序的栏位存在null值,且要指定NULL值排在最前面或者最后面,


在order by 的时候,用Nvl、NVL2 、Decode、case .....when....end;等函数对栏位的null值进行处理。

排序要看用什么字段排序,可以单个字段,也可以多个字段,这些与存在值是否为null无关。
如下列数据


id name class
1     a        1
2     b       null
3     c        null




现在要按id和class排序,其中id为主要排序字段,class为次要排序字段


可写如下语句


select * from 表名 order by id,class。

没有 order by 子句的 Oracle 排序结果集

【中文标题】没有 order by 子句的 Oracle 排序结果集【英文标题】:Oracle ordered resultset without order by clause 【发布时间】:2014-01-01 12:44:47 【问题描述】:

有没有一种方法可以在不实际使用“ORDER BY”子句的情况下从 oracle 表中获取“有序”结果集?

我正在开发一个从 oracle 表(没有唯一列)中读取数据的应用程序,我想引入某种恢复机制,以便在查询失败(例如获取期间的网络错误)的情况下避免读取行已经提取了。

应用程序是使用oracle OCI开发的,目前使用的是简单的选择查询。

是否有任何有效的机制来实现这一点?

【问题讨论】:

恕我直言,如果它没有唯一的列,这不是关系理论意义上的真正表格。您应该添加一些PK并使用它。 在数据仓库中,表中没有主键并不罕见 不,没有ORDER BY,就无法从表中获取一致排序的数据。总是有ROWID,但使用它需要您自担风险。 docs.oracle.com/cd/B19306_01/server.102/b14200/…。但当然,如果删除并插入同一行,它可能会得到不同的 rowid。 【参考方案1】:

在某些非常特殊的情况下,您可以在没有任何 ORDER BY 子句的情况下定义结果顺序。但是,您不应依赖这一点,Oracle 可能随时更改此行为。

也许您可以计算总行数(在查询执行后读取SQL%ROWCOUNT)并检查此数字与您客户端上收到的记录。

【讨论】:

【参考方案2】:

正如 Wernfried 指出的,如果没有 any ORDER BY,就没有可靠的方法来获得有序的结果。但问题假设 ORDER BY 是不可能的,因为没有唯一的列。至少有两种解决方法。

1. ROWID。 每个 Oracle 行都有一个唯一的伪列 ROWID。应用程序可以ORDER BY ROWID,存储最新的ROWID,然后使用WHERE ROWID &lt;= :rowid 从中断处继续。请注意,如果表格被修改或移动,ROWIDs 可以更改。

2。 ROW_NUMBER。 另一种选择是对所有数据进行排序并跟踪重复项。如果两行完全相同,则返回和处理哪些重复并不重要。查询和应用程序只需要跟踪其中有多少已被处理。然后它可以稍后处理其余部分。

drop table test1;

create table test1(a number);
insert into test1 values(1);
insert into test1 values(1);
insert into test1 values(2);
commit;

select a ,row_number() over (order by a /*and all other columns*/) rowNumber
from test1
order by rowNumber

A  ROWNUMBER
1  1          --Am I the real #1?  It doesn't matter.
1  2
2  3

如果在第一行之后出现故障,添加谓词 where rownumber &gt; :last_rownumber_processed 将获取其余行。第二个查询可能返回“第一个”1 而不是“第二个”1,但应用程序不会关心。与第一种解决方法一样,如果数据在运行之间发生变化,这将失败。

无论哪种方式,查询都必须为排序付费:

----------------------------
| Id  | Operation          |
----------------------------
|   0 | SELECT STATEMENT   |
|   1 |  WINDOW SORT       |
|   2 |   TABLE ACCESS FULL|
----------------------------

【讨论】:

【参考方案3】:

案例 1:

为了实现简单的恢复机制,唯一简单的方法就是使用RowID。

select t?.rowid, t1.*, t2.*, t3.* 
 from table1 t1, 
      table2 t2,
      table3 t3
where t1.? = t2.?
  and t2.? = t3.?
  and t?.rowid > :rowidProcessedPriorNetworkFailure
 order by t?.rowid 

t?.rowid 的原因是因为您必须选择叶子表。

在以下情况下,您应该选择 t3 作为 t?。 T2 - T1 :一个 T2 记录可能有一个或多个 T1 记录 T1 - T3 : 一个 T1 记录可能有一个或多个 T3 记录

但请记住,只要 Oracle 维护底层物理结构(即碎片整理、重组、将表移动到新数据文件),RowID 就会发生变化

案例 2:

如果是连接,则选择叶子表。 选择具有最多不同值的列。按该列排序。并且每当您必须恢复时,使用手头上的最后一个值完成反向操作。

希望这会对您有所帮助。

【讨论】:

【参考方案4】:

我使用以下查询来获取有序输出,而不使用“order by”字样。在这里,我想在不使用 order by 子句的情况下对 empno 进行排序。

查询:

Select empno, sal, deptno, max(sal) over(partition by empno) from emp;

但是您可以排除除 empno 和 max() 分析函数之外的任何列。

如果您有任何问题,请告诉我。

【讨论】:

没有。如果没有Order By,则无法保证您的结果将按任何特定顺序排列。 你是想回答还是问什么? 嗨尼克,如果您为查询运行解释计划,“选项”列将具有“排序”。如果您得到不同的结果,请告诉我。

以上是关于oracle使用order by排序null值如何处理的主要内容,如果未能解决你的问题,请参考以下文章

Oracle order by 处理NULL值

MySQL中order by中关于NULL值的排序问题

order by 升序排序是null字段如何排在最后?

MySQL进阶5--分组排序和分组查询 group by(having) /order by

PostgreSQL order by 排序问题

Oracle Order By排序用法详解