rownum详解
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀。 (1) rownum 对于等于某值的查询条件 (2)rownum对于大于某值的查询条件 (3)rownum对于小于某值的查询条件 查询rownum在某区间的数据,必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。 (4)rownum和排序??? 取得某列中第N大的行 select column_name from? select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)? select * from tablename? 注意:只能用以上符号(<、<=、!=)。 select * from tablename where rownum != 10;返回的是前9条记录。? 另外,这个方法更快: select * from (? 要先排序再选则须用select嵌套:内层排序外层选。? 1: 假如判定条件是常量,则:? 2: 假如判定值不是常量,则: 若条件是 = var,则只有当 var 为1 的时候才满足条件,这个时候不存在 stop key,必须进行full scan,对每个满足其他where条件的数据进行判定,选出一行后才能去选rownum=2的行…… ? 以下摘自《中国IT实验室》 1.在ORACLE中实现SELECT TOP N ???由于ORACLE不支持SELECT TOP语句,所以在ORACLE中经常是用ORDER BY跟ROWNUM的组合来实现SELECT TOP N的查询。 简单地说,实现方法如下所示: SELECT 列名1...列名n FROM ??? (SELECT 列名1...列名n FROM?表名?ORDER BY?列名1...列名n) ?? WHERE ROWNUM <= N(抽出记录数) ORDER BY ROWNUM ASC ???下面举个例子简单说明一下。 顾客表customer(id,name)有如下数据: ID NAME ?? 01 first ?? 02 Second ?? 03 third ?? 04 forth ?? 05 fifth ?? 06 sixth ?? 07 seventh ?? 08 eighth ?? 09 ninth ?? 10 tenth ?? 11 last ???则按NAME的字母顺抽出前三个顾客的SQL语句如下所示: SELECT * FROM ??? (SELECT * FROM CUSTOMER ORDER BY NAME) ?? WHERE ROWNUM <= 3 ?? ORDER BY ROWNUM ASC ???输出结果为: ID NAME ?? 08 eighth ?? 05 fifth ?? 01 first 2.在TOP N纪录中抽出第M(M <= N)条记录 ROWNUM是记录表中数据编号的一个隐藏子段,所以可以在得到TOP N条记录的时候同时抽出记录的ROWNUM,然后再从这N条记录中抽取记录编号为M的记录,即使我们希望得到的结果。 从上面的分析可以很容易得到下面的SQL语句。 SELECT?列名1...列名n?FROM ???? ( ???? SELECT ROWNUM RECNO,?列名1...列名nFROM ?????? (SELECT?列名1...列名n?FROM?表名?ORDER BY?列名1...列名n) ???? WHERE ROWNUM <= N(抽出记录数) ?? ORDER BY ROWNUM ASC ???? ) ?? WHERE RECNO =?M(M <= N) 同样以上表的数据为基础,那么得到以NAME的字母顺排序的第二个顾客的信息的SQL语句应该这样写: ?? SELECT ID,NAME FROM ???? ( ????? SELECT ROWNUM RECNO,ID,NAME FROM ??????? (SELECT * FROM CUSTOMER ORDER BY NAME) ???????? WHERE ROWNUM <= 3 ???????? ORDER BY ROWNUM ASC ) ?????? WHERE RECNO = 2 ?????结果则为: ?? ID NAME ??? 05 fifth 3.抽出按某种方式排序的记录集中的第N条记录 ???在2的说明中,当M = N的时候,即为我们的标题讲的结果。实际上,2的做法在里面N>M的部分的数据是基本上不会用到的,我们仅仅是为了说明方便而采用。 ???如上所述,则SQL语句应为: SELECT?列名1...列名n?FROM ???? ( ????? SELECT ROWNUM RECNO,?列名1...列名nFROM ??????? (SELECT?列名1...列名n?FROM?表名?ORDER BY?列名1...列名n) ???????? WHERE ROWNUM <= N(抽出记录数) ????? ORDER BY ROWNUM ASC ???? ) ???? WHERE RECNO = N ?????那么,2中的例子的SQL语句则为: ??? SELECT ID,NAME FROM ????? ( ?????? SELECT ROWNUM RECNO,NAME FROM ???????? (SELECT * FROM CUSTOMER ORDER BY NAME) ?????? WHERE ROWNUM <= 2 ?????? ORDER BY ROWNUM ASC ????? ) ????? WHERE RECNO = 2 ?????结果为: ?? ID NAME ??? 05 fifth 4.抽出按某种方式排序的记录集中的第M条记录开始的X条记录 ?? 3里所讲得仅仅是抽取一条记录的情况,当我们需要抽取多条记录的时候,此时在2中的N的取值应该是在N >= (M + X - 1)这个范围内,当让最经济的取值就是取等好的时候了的时候了。当然最后的抽取条件也不是RECNO = N了,应该是RECNO BETWEEN?M AND (M + X - 1)了,所以随之而来的SQL语句则为: ?? SELECT?列名1...列名n?FROM ??? ( ???? SELECT ROWNUM RECNO,?列名1...列名nFROM ????? ( ????? SELECT?列名1...列名n?FROM?表名?ORDER BY?列名1...列名n) ????? WHERE ROWNUM <= N?(N >= (M + X - 1)) ??? ORDER BY ROWNUM ASC ????? ) ???? WHERE RECNO BETWEEN?M AND (M + X - 1) ????同样以上面的数据为例,则抽取NAME的字母顺的第2条记录开始的3条记录的SQL语句为: ?? SELECT ID,NAME FROM ??????? (SELECT * FROM CUSTOMER ORDER BY NAME) ????? WHERE ROWNUM <= (2 + 3 - 1) ????? ORDER BY ROWNUM ASC ???? ) ???? WHERE RECNO BETWEEN 2 AND (2 + 3 - 1) ?????结果如下: ?? ID NAME ??? 05 fifth ??? 01 first ?? 04 forth ????以此为基础,再扩展的话,做成存储过程,将开始记录数以及抽取记录数为参数,就可以轻松实现分页抽取数据。 ? ROW_NUMBER()说明:返回结果集分区内行的序列号,每个分区的第一行从 1 开始。语法:ROW_NUMBER () OVER ([ <partition_by_clause>]<order_by_clause> ) 。备注:ORDERBY 子句可确定在特定分区中为行分配唯一 ROW_NUMBER 的顺序。参数:<partition_by_clause> :将FROM 子句生成的结果集划入应用了 ROW_NUMBER 函数的分区。<order_by_clause>:确定将 ROW_NUMBER 值分配给分区中的行的顺序。返回类型:bigint 。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |