详细说明
ROWNUM 是一个伪列,不是真正的列,在表中并不真实存在,它表从数据文件或缓冲区中读取数据的顺序。ROWNUM 不是行号。
ROWNUM 是对符合条件结果的序列号。它总是从 1 开始步长为 1 递增排起的。如果条件符合要求,ROWNUM 进入了结果集,接下来 ROWNUM 才会为 2,如果 ROWNUM 没有进入结果集,也就是 ROWNUM=1 时不符合条件,接下来 ROWNUM 还是为 1。
Oceanbase 使用 COUNT 算子 用于兼容 Oracle 的 ROWNUM 功能,实现 ROWNUM 表达式的自增操作。
在一般场景下,当 SQL 查询含有 ROWNUM 时,SQL 优化器就会在生成执行计划的时候分配一个 COUNT 算子。
ROWNUM 对应的表达式的初始值为 1,数据每通过一次 COUNT 算子,COUNT 算子就会为 ROWNUM 对应的表达式的值加上 1,实现 ROWNUM 表达式的自增操作。
放在 ON 里面无法保证让 ROWNUM=1 在 COUNT 算子中执行,从而无法能保证 ROWNUM 正确生效。
下面例子中,ROWNUM=1 是在 5 号算子上的,所以 5 号算子计算的时候如果 2 号 COUNT 算子还没有吐行,那么 ROWNUM=1 算出来就都是 true。 或者虽然5号算子只吐出了 1 行,但是上层连接出了多行,也可能造成最终结果不是 1 行。

而在下面的计划中,ROWNUM=1 是在 0 号 COUNT 算子上的,能够保证结果的正确性。

但是 ROWNUM=1 在复杂 SQL 执行中,不能保证是在 COUNT 算子上输出的,所以无法保证执行结果的正确性。
如果想要控制最终输出的结果集大小,可以在这个查询完成后使用 ROWNUM。
影响租户
影响 OceanBase 数据库中的 Oracle 租户,对于 SYS 租户和 MySQL 租户无影响。
适用版本
OceanBase 数据库 V3.x、V4.x 版本。