Oracle关键字rownum的使用
Oracle关键字rownum的使用
Rownum是oracle提供的一个伪列,我们用的比较多的地方是在做分页的时候。
如果对rownum使用不当,往往会出现一些比较抓狂的现象。
假如有表结构如下:
www.zzzyk.com
tid tname ttype
5 T1 Q1
4 T4 Q1
3 T3 Q7
2 T2 Q2
1 T1 Q6
6 T6 Q1
7 T7 Q3
8 T8 Q3
9 T9 Q4
10 T10 Q5
执行语句:SELECT rownum,t.* FROM t_test t ORDER BY t.tid;
预期的结果应该是: www.zzzyk.com
rownum tid tname ttype
1 1 T1 Q6
2 2 T2 Q2
3 3 T3 Q7
4 4 T4 Q1
5 5 T1 Q1
6 6 T6 Q1
7 7 T7 Q3
8 8 T8 Q3
9 9 T9 Q4
10 10 T10 Q5
而真实结果确实:
rownum tid tname ttype
5 1 T1 Q6
4 2 T2 Q2
3 3 T3 Q7
2 4 T4 Q1
1 5 T1 Q1
6 6 T6 Q1
7 7 T7 Q3
8 8 T8 Q3
9 9 T9 Q4
10 10 T10 Q5
产生的结果并没有按我们预期的先排序再生成rownum值,生成的rownum值是按照我们添加数据时的顺序。
产生这种结果可以有两种方式解决:
1、order by 字段建立主键约束
2、将rownum提到外层使用,语句:
SELECT ROWNUM,tt.* FROM (
SELECT * FROM t_test t
)tt
采用这两种方式之一,输出的结果就同我们预想的一样。
但是,在使用的过程中发现了另外一个问题,在对分组字句使用rownum时显示乱序。
sql语句:
SELECT * FROM (
SELECT MAX(t.tid),MAX(t.tname),t.ttype FROM t_test t GROUP BY t.ttype
) tt WHERE ROWNUM<3
执行结果并没有如预期显示子查询结果的前两行数据。
www.zzzyk.com
解决方法有两个:
1、分组内部先排序
SELECT * FROM (
SELECT MAX(t.tid),MAX(t.tname),t.ttype FROM t_test t GROUP BY t.ttype ORDER BY MAX(t.tid)
) tt WHERE ROWNUM<3
2、分组外多包层查询
SELECT ttt.* FROM (
SELECT ROWNUM row_num,tt.* FROM (
SELECT MAX(t.tid),MAX(t.tname),t.ttype FROM t_test t GROUP BY t.ttype
) tt
) ttt WHERE ROWNUM<3