当你从某个表中查询数据的时候,返回的结果集中都会带有rownum这个字段,而且有时候也可以使用rownum进行一些条件查询。rownum是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列 (
强调:先要有结果集)。简单的说 rownum 是对符合条件结果的序列号。
它总是从1开始排起的,所以你选出的结果不可能没有1,而有其他大于1的值。
注意:rownum不能以任何基表的名称作为前缀
Oracle在检索数据的时候,会首先把数据都检索出来,然后在排序段中进行排序。
1.rownum等于某值的查询
SQL> select hs_login from t_users where rownum = 1;
HS_LOGIN
--------------------------------------------------
admin1
SQL> select hs_login from t_users where rownum = 2;
no rows selected
rownum都是从1开始,1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。
2.rownum大于某值的查询
SQL> select hs_login from t_users where rownum > 990;
no rows selected
我们可以通过子查询的方式来解决;但是
子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL> set timing on
SQL> select rownum, hs_login from (select rownum as rn, hs_login from t_users) where rn > 990;
ROWNUM HS_LOGIN
---------- --------------------------------------------------
1 admin991
2 admin992
3 admin993
4 admin994
5 admin995
6 admin996
7 admin997
8 admin998
9 admin999
9 rows selected.
Elapsed: 00:00:00.07
查询rownum在某区间的数据,必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。
但是这样的操作会在大数据集中影响速度。
SQL> select rownum, hs_uuid, hs_login from (select rownum rn, hs_uuid, hs_login from t_users where rownum < 5) where rn > 2;
ROWNUM HS_UUID HS_LOGIN
---------- ---------- --------------------------------------------------
1 3 admin3
2 4 admin4
3.rownum小于某值的查询
rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录。
SQL> select rownum, hs_login from t_users where rownum < 5 order by hs_login;
ROWNUM HS_LOGIN
---------- --------------------------------------------------
1 admin1
2 admin10
3 admin100
4 admin101
Elapsed: 00:00:00.04
oracle却不能按自己的意愿来执行,而是先随便取4条记录,然后再order by。
如果通过子查询先排序再rownum的话,测试发现也不行,而且当大数据量时效率太低。
SQL> set timing on
SQL> select rownum, hs_uuid, hs_login from (select * from t_users order by hs_login) where rownum < 5;
ROWNUM HS_UUID HS_LOGIN
---------- ---------- --------------------------------------------------
1 1 admin1
2 10 admin10
3 100 admin100
4 101 admin101
Elapsed: 00:00:00.03
在order by 的字段上加索引让oracle先按该字段排序,然后再rownum。
SQL> create index login_index on T_USERS('hs_login');
Index created.
Elapsed: 00:00:00.91
SQL> select rownum, hs_login from t_users where rownum < 5 order by hs_login;
ROWNUM HS_LOGIN
---------- --------------------------------------------------
1 admin1
2 admin10
3 admin100
4 admin101
Elapsed: 00:00:00.05
4.rownum和排序
Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据取指定的rowmun行数据就必须注意了。
举例1
SQL> select rownum, hs_login from t_users where rownum < 5 order by hs_login;
ROWNUM HS_LOGIN
---------- --------------------------------------------------
1 admin1
2 admin10
3 admin100
4 admin101
Elapsed: 00:00:00.04
举例2
SQL> select rownum, hs_uuid,hs_login from t_users where rownum < 5 order by hs_login;
ROWNUM HS_UUID HS_LOGIN
---------- ---------- --------------------------------------------------
1 1 admin1
2 2 admin2
3 3 admin3
4 4 admin4
Elapsed: 00:00:00.04
举例3
SQL> select rownum, hs_uuid,hs_login from t_users where rownum < 5;
ROWNUM HS_UUID HS_LOGIN
---------- ---------- --------------------------------------------------
1 1 admin1
2 2 admin2
3 3 admin3
4 4 admin4
Elapsed: 00:00:00.10
<<To Be Continued>>