如何在Oracle数据库中跳过/偏移行?

时间:2016-12-06 14:27:02

标签: sql oracle

我正在为Oracle DB(版本9)编写一个非常简单的查询。

不知怎的,我可以获得前5行:

select * from cities where rownum <= 5

但跳过5行会返回一个空结果:

select * from cities where rownum >= 5

使用:

  • Oracle SQL Developer
  • Oracle DB版本9

为什么第二个查询返回空结果?

7 个答案:

答案 0 :(得分:3)

每次向结果集添加行时,Oracle都会增加rownum。所以说rownum < 5很好;因为它会添加前5行中的每一行,所以它会增加rownum,但是一旦ruwnum = 5 WHERE子句停止匹配,就不会有更多行添加到结果中,尽管你没有&#39} ; t注意这个rownum停止递增。

但是,如果你说WHERE rownum > 5然后马上就可以了,那么WHERE条款就不匹配了;因为,比方说,第一行没有添加到结果集中,rownum不会增加...所以rownum永远不会达到大于5的值而{ {1}}子句永远不会匹配。

要获得所需的结果,可以在子查询中使用WHERE,例如

row_number() over()

更新 - 正如其他人所说,只有这样,这种查询才有意义 控制行编号的顺序,所以你应该真正使用select * from (select row_number() over() rn, -- other values from table where -- ...) where rn > 5 某些东西 row_number() over(order by其中某些东西是一个有用的排序键,用于决定哪些记录是&#34;前5个记录&#34;。

答案 1 :(得分:2)

您可以使用以下查询跳过第一行而不是n行。

select * from (
 select rslts.*, rownum as rec_no from (
  <<Query with proper order by (If you don't have proper order by you will see weird results)>>
 ) rslts
) where  rec_no > <<startRowNum - n>>

以上查询类似于下面的分页查询。

select * from (
 select rslts.*, rownum as rec_no from (
  <<Query with proper order by (If you don't have proper order by you will see weird results)>>
 ) rslts where  rownum <= <<endRowNum>>
) where  rec_no > <<startRowNum>>

您的城市查询:

select * from (
 select rslts.*, rownum as rec_no from (
  select * from cities order by 1
 ) rslts
) where  rec_no > 5 <<startRowNum>>

注意:假设cities表中的第一列是唯一键

答案 2 :(得分:1)

使用row_number() over (order by id)

select * from
(select row_number() over (order by id) rn, c.* from countries c)
where rn > 5

使用ROWNUM

select * from
(select rownum rn, c.* from countries c)
where rn > 5

重要提示:

需要使用别名countries c而不是countries!如果没有,则会出现错误"missing expression"

答案 3 :(得分:1)

在Oracle Database 12c(版本1)及更高版本中,您可以非常简单地跳过5行:

SELECT * FROM T OFFSET 5 ROWS

并跳过5行并进行15行:

SELECT * FROM T OFFSET 5 ROWS FETCH NEXT 15 ROWS ONLY

答案 4 :(得分:0)

只有在输出一行时才会增加rownum,因此这种情况不会起作用。
无论如何,你没有订购你的行,那么重点是什么?

答案 5 :(得分:0)

使用此代码,您可以使用 skip take 查询表。

select * from (
 select a.*, rownum rnum from (
  select * from cities
 ) a
) WHERE rnum >= :skip + 1 AND rnum <= :skip + :take

此代码可用于Oracle 11g。使用Oracle 12,已经有一种更好的方法来使用 offset fetch

来执行此查询。

答案 6 :(得分:0)

更好的是:

size

Sample子句指示在采样过程中每一行被拾取的概率。 FETCH NEXT子句指示您要选择的行数。