oracle的rownum深入解析


Oracle的`ROWNUM`是一个伪列,它为查询结果集中的每一行分配一个唯一的数字。这个数字在结果集被返回给用户之前就已经生成,并且它用于限制返回给用户的数据行数,或者进行分页查询等。以下是对`ROWNUM`的深入解析:

### 基本用法

`ROWNUM`在结果集的每一行上自动生成一个唯一的序号,从1开始。


SELECT * FROM (
  SELECT your_columns, ROWNUM rn
  FROM your_table
  WHERE your_conditions
  ORDER BY your_order_columns
)
WHERE rn <= 10; -- 限制只返回前10行

注意:在Oracle中,如果你直接在`WHERE`子句中使用`ROWNUM`进行过滤(如`WHERE ROWNUM <= 10`),然后再进行`ORDER BY`排序,可能会得到不是你预期的结果。因为`ROWNUM`是在结果集被排序之前分配的。

### 使用`ROWNUM`进行分页

由于`ROWNUM`在排序之前生成,所以如果你想通过`ROWNUM`来实现分页(比如获取第N页的数据,每页M条记录),你需要嵌套一个子查询或使用其他方法,比如`ROWNUM`与`ANALYTIC FUNCTIONS`结合使用。

#### 示例:获取第2页的数据,每页10条


SELECT * FROM (
  SELECT a.*, ROWNUM rn FROM (
    SELECT your_columns
    FROM your_table
    ORDER BY your_order_columns
  ) a
  WHERE ROWNUM <= (2 * 10) -- 第2页,所以是20
)
WHERE rn > (2 - 1) * 10; -- 排除前10条,即第1页的数据

### 注意事项

- `ROWNUM`是在结果集被生成后,但在它被返回给用户之前被赋值的。

- 不能在`ORDER BY`之前使用`ROWNUM`来过滤行,因为这将导致不正确的排序和过滤行为。

- 对于需要复杂分页逻辑的场景,可能需要考虑使用Oracle的`ROW_NUMBER()`等分析函数来替代简单的`ROWNUM`。

### 结论

`ROWNUM`是Oracle中一个非常有用的特性,用于限制查询结果的行数或实现简单的分页逻辑。然而,由于它的行为特性,对于复杂的分页需求,可能需要采用其他方法。