作者:丹愿人常久6688 | 来源:互联网 | 2014-07-08 01:11
Oracle学习笔记之数据库获取随机的n条记录最近在做公司的车联网服务系统,碰到一个需求,需要从数据库中获取随机的n条记录。我参照了《SQLCOOKBOOK》中提供的解决方案,现记笔记如下,分享给大家。www.2cto....SyntaxHighlighter.all();
最近在做公司的车联网服务系统,碰到一个需求,需要从数据库中获取随机的n条记录。
我参照了《SQL COOKBOOK》中提供的解决方案,现记笔记如下,分享给大家。
www.2cto.com
解决方案
使用DBMS支持的内置函数来产生随机数值。在ORDER BY字句中使用该函数,对记录进行随机排序,然后,使用ROWNUM限制返回的行(顺序随机)的数目。
探索步骤
1.查找满足条件的行
1 select ename,job,sal from emp where sal>2000
查询结果如下:
2.使用ORACLE支持的内置函数对记录进行排序
1 select ename,job,sal from emp where sal>2000 order by dbms_random.value
查询结果如下:
(每次生成的记录排序不同)
3.限制返回的行的数目
1 select * from
2 (
3 select ename,job,sal from emp where sal>2000 order by dbms_random.value
4 ) t
5 where rownum<=5;
查询结果如下:
(每次生成的记录及排序不同)
拓展知识
1.关于ROWNUM
许多数据库提供一些语句,比如FETCH FIRST和LIMIT,让用户指定从查询中返回的行数,
Oracle的做法则不同,必须使用ROWNUM函数来得到每行的行号(从1开始递增数值)。
在使用ROWNUM<=5来返回前5行时,会发生下面的操作:
Oracle执行查询
Oracle获取第1个符合条件的行,将它叫做第1行。
有5行了吗?如果没有,那么Oracle就再返回行,因为它要满足行号小于等于5的条件,如果到了5行,那么,Oracle将不再返回行。
Oracle获取下一行,并递增行号(从2,到3,再到4,等等)。
返回第3步。
可以看到,Oracle的ROWNUM数值是在获取每行之后才赋予的,这非常重要,是一个关键点。比如说,许多Oracle开发人员想通过指定ROWNUM=5来返回第5行,这是错误的做法。下面说明使用ROWNUM=5会发生什么:
Oracle执行查询。
Oracle获取第一个符合条件的行,将它叫做第1行。
有5行了吗?如果没有,那么Oracle就丢弃这些行,因为它不满足条件。如果到了5行,那么,Oracle就返回该行。但是,答案是,永远也不会有"到了5行"的情况发生。
Oracle获取下一行,这是第一行。原因是,从查询中返回的必须是编号为1的行。
转向第3步。
仔细看看这个过程,可以知道使用ROWNUM=5来返回第5行失败的原因。如果不返回第1行到第4行的话,就不会有第5行。
ROWNUM=1确实是返回第1行,这似乎与前面的说明矛盾了。原因是,ROWNUM=1返回第1行,不管表中是否有行,Oracle都会尝试至少取1行。请仔细看前面叙述的过程,将5换成1,就可以理解指定ROWNUM=1作为条件来返回1行为什么是可行的了。
如果要获取指定行数范围内的记录,可以采用分页查询的方式。
2.关于DBMS_RANDOM
一个简单的示例,如下图所示:
1 --DBMS_RANDOM
2 --该包提供了内置的随机数生成器,可以用于快速生成随机数。
3 --1.INITALIZE 该过程用于初始化DBMS_RANDOM包。在初始化DBMS_RANDOM包时,必须要提供随机数种子
4 --2.SEED 该过程用于复位随机数种子
5 --3.RANDOM 该过程用于生成随机数
6 --4.TERMINATE 该过程用于关闭DBMS_RANDOM包
7 --随机数使用示例
8 DECLARE
9 num INT;
10 seed NUMBER:=10000000;
11 BEGIN
12 dbms_random.initialize(seed);
13 FOR i IN 1..10 LOOP
14 num:=abs(dbms_random.random()/seed);
15 dbms_output.put_line(num);
16 END LOOP;
17 dbms_random.terminate;
18 END;
运行结果如下: