--------- Oracle 奇怪的 row_number() 函数,大家来分析一下..........-- 查询一:直接查询(无子查询时)scott@SZTYORA> select xh, xm,xh,zxf,row_number() over(order by zxf) rn from xs;XH XM XH ZXF RN
------------ ---------------------------------------- ------------ ---------- ----------
061202 王林 061202 40 1
061220 吴薇华 061220 42 2
061218 孙严 061218 42 3
061216 孙祥欣 061216 42 4
061221 刘燕敏 061221 42 5
061206 李计 061206 42 6
061201 王敏 061201 42 7
061204 马琳琳 061204 42 8
061203 王玉民 061203 42 9
061210 李红庆 061210 44 10
061241 罗林琳 061241 44 11
061113 严红 061113 48 12
061110 张蔚 061110 50 13
061109 张强民 061109 50 14
061106 李方方 061106 50 15
061101 王林 061101 50 16
061111 赵琳 061111 50 17
061104 韦严平 061104 50 18
061103 王燕 061103 50 19
061102 程明 061102 50 20
061108 林一帆 061108 52 21
061107 李明 061107 54 22已选择22行。--------------------------------------------------------------------------------------------- 查询二:有子查询(但外层查询无条件时,此时还跟查询一结果一致)scott@SZTYORA> select * from (
2 select ascii(xm) as asc_xm, xm,xh,zxf,row_number() over(order by zxf) rn from xs ) t; ASC_XM XM XH ZXF RN
---------- ---------------------------------------- ------------ ---------- ----------
15175307 王林 061202 40 1
15044788 吴薇华 061220 42 2
15052185 孙严 061218 42 3
15052185 孙祥欣 061216 42 4
15042712 刘燕敏 061221 42 5
15113614 李计 061206 42 6
15175307 王敏 061201 42 7
15313324 马琳琳 061204 42 8
15175307 王玉民 061203 42 9
15113614 李红庆 061210 44 10
15187351 罗林琳 061241 44 11
14989477 严红 061113 48 12
15056032 张蔚 061110 50 13
15056032 张强民 061109 50 14
15113614 李方方 061106 50 15
15175307 王林 061101 50 16
15250869 赵琳 061111 50 17
15310758 韦严平 061104 50 18
15175307 王燕 061103 50 19
15181963 程明 061102 50 20
15113879 林一帆 061108 52 21
15113614 李明 061107 54 22已选择22行。已用时间: 00: 00: 00.11--------------------------------------------------------------------------------------------- 查询三:有子查询(但外层查询有条件时,此时查询结果 RN 发生了变化,为什么呢?)scott@SZTYORA> select * from (
2 select ascii(xm) as asc_xm, xm,xh,zxf,row_number() over(order by zxf) rn from xs ) t
3 where t.rn>=10 and t.rn<=20; ASC_XM XM XH ZXF RN
---------- ---------------------------------------- ------------ ---------- ----------
15113614 李红庆 061210 44 10
15187351 罗林琳 061241 44 11
14989477 严红 061113 48 12
15175307 王林 061101 50 13
15181963 程明 061102 50 14
15175307 王燕 061103 50 15
15310758 韦严平 061104 50 16
15056032 张强民 061109 50 17
15250869 赵琳 061111 50 18
15056032 张蔚 061110 50 19
15113614 李方方 061106 50 20已选择11行。已用时间: 00: 00: 00.07-- 上面查询 RN 为13 的是“张蔚”,此时却查到的是“王林”,“ZXF”=50 的顺序都不太一样啦,也找不出是什么排序规律,
-- 所以求各位大虾:给个说法!
------------ ---------------------------------------- ------------ ---------- ----------
061202 王林 061202 40 1
061220 吴薇华 061220 42 2
061218 孙严 061218 42 3
061216 孙祥欣 061216 42 4
061221 刘燕敏 061221 42 5
061206 李计 061206 42 6
061201 王敏 061201 42 7
061204 马琳琳 061204 42 8
061203 王玉民 061203 42 9
061210 李红庆 061210 44 10
061241 罗林琳 061241 44 11
061113 严红 061113 48 12
061110 张蔚 061110 50 13
061109 张强民 061109 50 14
061106 李方方 061106 50 15
061101 王林 061101 50 16
061111 赵琳 061111 50 17
061104 韦严平 061104 50 18
061103 王燕 061103 50 19
061102 程明 061102 50 20
061108 林一帆 061108 52 21
061107 李明 061107 54 22已选择22行。--------------------------------------------------------------------------------------------- 查询二:有子查询(但外层查询无条件时,此时还跟查询一结果一致)scott@SZTYORA> select * from (
2 select ascii(xm) as asc_xm, xm,xh,zxf,row_number() over(order by zxf) rn from xs ) t; ASC_XM XM XH ZXF RN
---------- ---------------------------------------- ------------ ---------- ----------
15175307 王林 061202 40 1
15044788 吴薇华 061220 42 2
15052185 孙严 061218 42 3
15052185 孙祥欣 061216 42 4
15042712 刘燕敏 061221 42 5
15113614 李计 061206 42 6
15175307 王敏 061201 42 7
15313324 马琳琳 061204 42 8
15175307 王玉民 061203 42 9
15113614 李红庆 061210 44 10
15187351 罗林琳 061241 44 11
14989477 严红 061113 48 12
15056032 张蔚 061110 50 13
15056032 张强民 061109 50 14
15113614 李方方 061106 50 15
15175307 王林 061101 50 16
15250869 赵琳 061111 50 17
15310758 韦严平 061104 50 18
15175307 王燕 061103 50 19
15181963 程明 061102 50 20
15113879 林一帆 061108 52 21
15113614 李明 061107 54 22已选择22行。已用时间: 00: 00: 00.11--------------------------------------------------------------------------------------------- 查询三:有子查询(但外层查询有条件时,此时查询结果 RN 发生了变化,为什么呢?)scott@SZTYORA> select * from (
2 select ascii(xm) as asc_xm, xm,xh,zxf,row_number() over(order by zxf) rn from xs ) t
3 where t.rn>=10 and t.rn<=20; ASC_XM XM XH ZXF RN
---------- ---------------------------------------- ------------ ---------- ----------
15113614 李红庆 061210 44 10
15187351 罗林琳 061241 44 11
14989477 严红 061113 48 12
15175307 王林 061101 50 13
15181963 程明 061102 50 14
15175307 王燕 061103 50 15
15310758 韦严平 061104 50 16
15056032 张强民 061109 50 17
15250869 赵琳 061111 50 18
15056032 张蔚 061110 50 19
15113614 李方方 061106 50 20已选择11行。已用时间: 00: 00: 00.07-- 上面查询 RN 为13 的是“张蔚”,此时却查到的是“王林”,“ZXF”=50 的顺序都不太一样啦,也找不出是什么排序规律,
-- 所以求各位大虾:给个说法!
(
XH char(6) NOT NULL CONSTRAINT PK_XS_XH PRIMARY KEY,
XM varchar2(20) NOT NULL,
ZYM char(20) NULL,
XB char(4) NOT NULL CONSTRAINT CH_XS_XB CHECK(XB='男' or XB='女'),
CSSJ date NOT NULL,
ZXF number(2) NULL,
BZ varchar2(100) NULL
);INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061101','王林','计算机','男',TO_DATE('19860210','YYYYMMDD'),50);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061102','程明','计算机','男',TO_DATE('19870201','YYYYMMDD'),50);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061103','王燕','计算机','女',TO_DATE('19851006','YYYYMMDD'),50);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061104','韦严平','计算机','男',TO_DATE('19860826','YYYYMMDD'),50);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061106','李方方','计算机','男',TO_DATE('19861120','YYYYMMDD'),50);
INSERT INTO XS VALUES('061107','李明','计算机','男',TO_DATE('19861120','YYYYMMDD'),54,'提前修完《数据结构》,并获学分');
INSERT INTO XS VALUES('061108','林一帆','计算机','男',TO_DATE('19850805','YYYYMMDD'),52,'已提前修完一门课');
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061109','张强民','计算机','男',TO_DATE('19840811','YYYYMMDD'),50);
INSERT INTO XS VALUES('061110','张蔚','计算机','女',TO_DATE('19870722','YYYYMMDD'),50,'三好生');
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061111','赵琳','计算机','女',TO_DATE('19860318','YYYYMMDD'),50);
INSERT INTO XS VALUES('061113','严红','计算机','女',TO_DATE('19850811','YYYYMMDD'),48,'有一门功课不及格,待补考');
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061201','王敏','通信工程','男',TO_DATE('19840110','YYYYMMDD'),42);
INSERT INTO XS VALUES('061202','王林','通信工程','男',TO_DATE('19850129','YYYYMMDD'),40,'有一门功课不及格,待补考');
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061203','王玉民','通信工程','男',TO_DATE('19860326','YYYYMMDD'),42);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061204','马琳琳','通信工程','女',TO_DATE('19840210','YYYYMMDD'),42);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061206','李计','通信工程','女',TO_DATE('19850920','YYYYMMDD'),42);
INSERT INTO XS VALUES('061210','李红庆','通信工程','女',TO_DATE('19850501','YYYYMMDD'),44,'已提前修完一门课,并获得学分');INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061216','孙祥欣','通信工程','女',TO_DATE('19840309','YYYYMMDD'),42);INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061218','孙严','通信工程','男',TO_DATE('19861009','YYYYMMDD'),42);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061220','吴薇华','通信工程','女',TO_DATE('19860318','YYYYMMDD'),42);
INSERT INTO XS(XH,XM,ZYM,XB,CSSJ,ZXF) VALUES('061221','刘燕敏','通信工程','女',TO_DATE('19851112','YYYYMMDD'),42);
INSERT INTO XS VALUES('061241','罗林琳','通信工程','女',TO_DATE('19860130','YYYYMMDD'),44,'转专业学习');commit;
------------------ ------------ -------------------- -------------------- -------- -------------- ---------- ---------
AAAM0KAAEAAAA4WAAA 061101 王林 计算机 男 10-2月 -86 50
AAAM0KAAEAAAA4WAAB 061102 程明 计算机 男 01-2月 -87 50
AAAM0KAAEAAAA4WAAC 061103 王燕 计算机 女 06-10月-85 50
AAAM0KAAEAAAA4WAAD 061104 韦严平 计算机 男 26-8月 -86 50
AAAM0KAAEAAAA4WAAE 061106 李方方 计算机 男 20-11月-86 50
AAAM0KAAEAAAA4WAAH 061109 张强民 计算机 男 11-8月 -84 50
AAAM0KAAEAAAA4WAAI 061110 张蔚 计算机 女 22-7月 -87 50 三好生
AAAM0KAAEAAAA4WAAJ 061111 赵琳 计算机 女 18-3月 -86 50已选择8行。已用时间: 00: 00: 00.09
scott@SZTYORA> select rowid, t.* from xs t where zxf=50 order by rownum;ROWID XH XM ZYM XB CSSJ ZXF BZ
------------------ ------------ -------------------- -------------------- -------- -------------- ---------- ---------
AAAM0KAAEAAAA4WAAA 061101 王林 计算机 男 10-2月 -86 50
AAAM0KAAEAAAA4WAAB 061102 程明 计算机 男 01-2月 -87 50
AAAM0KAAEAAAA4WAAC 061103 王燕 计算机 女 06-10月-85 50
AAAM0KAAEAAAA4WAAD 061104 韦严平 计算机 男 26-8月 -86 50
AAAM0KAAEAAAA4WAAE 061106 李方方 计算机 男 20-11月-86 50
AAAM0KAAEAAAA4WAAH 061109 张强民 计算机 男 11-8月 -84 50
AAAM0KAAEAAAA4WAAI 061110 张蔚 计算机 女 22-7月 -87 50 三好生
AAAM0KAAEAAAA4WAAJ 061111 赵琳 计算机 女 18-3月 -86 50已选择8行。
Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
Connected as scott
-- ZXF=50 的 其他的 RN 都对吗?
-- 我用的是 Oracle 10g (10.2.0.4)
取出来的记录数竟然不一样多的
一直也没找出原因来
10G以后不会,
刚想了想,
你最后两句
select rowid, t.* from xs t where zxf=50 order by rowid;
得到的结果是正确的顺便,那么
select rowid, t.* from xs t where zxf=50 order by rownum;t.rn>=10 and t.rn<=20,触发了按照ROWID排序,猜想是如此的你测试下,select xh, xm,xh,zxf,row_number() over(order by zxf) rn from xs order by rowid;试试
--------- Oracle 奇怪的 row_number() 函数,大家来分析一下..........-- 查询一:直接查询(无子查询时)scott@SZTYORA> select xh, xm,xh,zxf,row_number() over(order by zxf,rowid) rn from xs;
XH XM XH ZXF RN
------------ ---------------------------------------- ------------ ---------- ----------
061202 王林 061202 40 1
061201 王敏 061201 42 2
061203 王玉民 061203 42 3
061204 马琳琳 061204 42 4
061206 李计 061206 42 5
061216 孙祥欣 061216 42 6
061218 孙严 061218 42 7
061220 吴薇华 061220 42 8
061221 刘燕敏 061221 42 9
061210 李红庆 061210 44 10
061241 罗林琳 061241 44 11
061113 严红 061113 48 12
061101 王林 061101 50 13
061102 程明 061102 50 14
061103 王燕 061103 50 15
061104 韦严平 061104 50 16
061106 李方方 061106 50 17
061109 张强民 061109 50 18
061110 张蔚 061110 50 19
061111 赵琳 061111 50 20
061108 林一帆 061108 52 21
061107 李明 061107 54 22已选择22行。已用时间: 00: 00: 00.10--------------------------------------------------------------------------------------------- 查询二:有子查询(但外层查询无条件时,此时还跟查询一结果一致)scott@SZTYORA> select * from (
2 select ascii(xm) as asc_xm, xm,xh,zxf,row_number() over(order by zxf,rowid) rn from xs ) t; ASC_XM XM XH ZXF RN
---------- ---------------------------------------- ------------ ---------- ----------
15175307 王林 061202 40 1
15175307 王敏 061201 42 2
15175307 王玉民 061203 42 3
15313324 马琳琳 061204 42 4
15113614 李计 061206 42 5
15052185 孙祥欣 061216 42 6
15052185 孙严 061218 42 7
15044788 吴薇华 061220 42 8
15042712 刘燕敏 061221 42 9
15113614 李红庆 061210 44 10
15187351 罗林琳 061241 44 11
14989477 严红 061113 48 12
15175307 王林 061101 50 13
15181963 程明 061102 50 14
15175307 王燕 061103 50 15
15310758 韦严平 061104 50 16
15113614 李方方 061106 50 17
15056032 张强民 061109 50 18
15056032 张蔚 061110 50 19
15250869 赵琳 061111 50 20
15113879 林一帆 061108 52 21
15113614 李明 061107 54 22已选择22行。已用时间: 00: 00: 00.06--------------------------------------------------------------------------------------------- 查询三:有子查询(但外层查询有条件时,此时查询结果 RN 发生了变化,为什么呢?)
scott@SZTYORA> select * from (
2 select ascii(xm) as asc_xm, xm,xh,zxf,row_number() over(order by zxf,rowid) rn from xs ) t
3 where t.rn>=10 and t.rn<=23; ASC_XM XM XH ZXF RN
---------- ---------------------------------------- ------------ ---------- ----------
15113614 李红庆 061210 44 10
15187351 罗林琳 061241 44 11
14989477 严红 061113 48 12
15175307 王林 061101 50 13
15181963 程明 061102 50 14
15175307 王燕 061103 50 15
15310758 韦严平 061104 50 16
15113614 李方方 061106 50 17
15056032 张强民 061109 50 18
15056032 张蔚 061110 50 19
15250869 赵琳 061111 50 20
15113879 林一帆 061108 52 21
15113614 李明 061107 54 22已选择13行。已用时间: 00: 00: 00.01
2 49886 罗林琳 61241 44 11
3 53711 严红 61113 48 12
4 54725 张蔚 61110 50 13
5 54725 张强民 61109 50 14
6 49390 李方方 61106 50 15
7 52725 王林 61101 50 16
8 54740 赵琳 61111 50 17
9 52900 韦严平 61104 50 18
10 52725 王燕 61103 50 19
11 46028 程明 61102 50 20
是正确的 ,order by zxf,rowid 相同的zxf 按插入时的物理地址排序是正确的 顶
select *
from (select ascii(xm) as asc_xm,
xm,
xh,
zxf,
row_number() over( order by zxf) rn
from xs) t
where t.rn >=13
minusselect *
from (select ascii(xm) as asc_xm,
xm,
xh,
zxf,
row_number() over( order by zxf) rn
from xs) t
where t.rn >=21
--这个在大于不等式下应该是稳定的,但是如果是小于不等式的话就好像是按另一个排序了,这个问题真得问ORACLE啊
怪哉
from (select ascii(xm) as asc_xm,
xm,
xh,
zxf,
row_number() over( order by zxf) rn
from xs) t
where t.rn <24 minus select *
from (select ascii(xm) as asc_xm,
xm,
xh,
zxf,
row_number() over( order by zxf) rn
from xs) t
where t.rn <13
-- and
--t.rn <= 100;--如果你运行以上的语句,将一团糟糕,意料之外
Rank() 排序不会显示连续的编号
Dense_Rank()会连续显示编号
Ntile(n) 根据制定的分组将结果集分区(partition) 并记录其在组中所在的位置。pivot(<聚合函数> for pivot 字段 in(字段列表))其实这几个函数你可以了解一下,
order by zxf,rowid或者找个能够保证唯一的列
SQL> set autot trace explain
SQL> select xh,xm,xh,zxf,row_number()over(order by zxf) rn from xs;执行计划
----------------------------------------------------------
Plan hash value: 219165360
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 726 | 4 (25)| 00:00:01 |
| 1 | WINDOW SORT | | 22 | 726 | 4 (25)| 00:00:01 |
| 2 | TABLE ACCESS FULL| XS | 22 | 726 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement SQL> select * from (select xh,xm,zxf,row_number()over(order by zxf) rn from xs) where rn>=10 and rn<=20执行计划
----------------------------------------------------------
Plan hash value: 2407451311
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1012 | 4 (25)| 00:00:01 |
|* 1 | VIEW | | 22 | 1012 | 4 (25)| 00:00:01 |
|* 2 | WINDOW SORT PUSHED RANK| | 22 | 726 | 4 (25)| 00:00:01 |
| 3 | TABLE ACCESS FULL | XS | 22 | 726 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------- Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN">=10 AND "RN"<=20)
2 - filter(ROW_NUMBER() OVER ( ORDER BY "ZXF")<=20)
Note
-----
- dynamic sampling used for this statement
一个是WINDOW SORT,一个是WINDOW SORT PUSHED RANK
具体区别我也说不清楚
这个排序的不确定性在分页时会造成困扰
可以加上rowid来解决
问题就出在你有相同的数据ZXF=50的那些
而你只有一个order by zxf
一样的值 你让ORACLE怎么给你排 呵呵
你加个其他字段在后面 只要唯一 也可以保证每次查询出的结果正确