Oracle学习笔记之数据库获取随机的n条记录
2012-11-13 11:18
218 查看
最近在做公司的车联网服务系统,碰到一个需求,需要从数据库中获取随机的n条记录。我参照了《SQL COOKBOOK》中提供的解决方案,现记笔记如下,分享给大家。
(每次生成的记录排序不同)
(每次生成的记录及排序不同)
在使用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行为什么是可行的了。
如果要获取指定行数范围内的记录,可以采用分页查询的方式。
本文出自 “快乐编程” 博客,请务必保留此出处http://hqwanghai.blog.51cto.com/5869403/1058710
解决方案
使用DBMS支持的内置函数来产生随机数值。在ORDER BY字句中使用该函数,对记录进行随机排序,然后,使用ROWNUM限制返回的行(顺序随机)的数目。探索步骤
1.查找满足条件的行
select ename,job,sal from emp where sal>2000
查询结果如下:
2.使用ORACLE支持的内置函数对记录进行排序
select ename,job,sal from emp where sal>2000 order by dbms_random.value
(每次生成的记录排序不同)
3.限制返回的行的数目
select * from
(
select ename,job,sal from emp where sal>2000 order by dbms_random.value) t
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
一个简单的示例,如下图所示:--DBMS_RANDOM --该包提供了内置的随机数生成器,可以用于快速生成随机数。 --1.INITALIZE 该过程用于初始化DBMS_RANDOM包。在初始化DBMS_RANDOM包时,必须要提供随机数种子 --2.SEED 该过程用于复位随机数种子 --3.RANDOM 该过程用于生成随机数 --4.TERMINATE 该过程用于关闭DBMS_RANDOM包 --随机数使用示例 DECLARE num INT; seed NUMBER:=10000000; BEGIN dbms_random.initialize(seed); FOR i IN 1..10 LOOP num:=abs(dbms_random.random()/seed); dbms_output.put_line(num); END LOOP; dbms_random.terminate; END;
本文出自 “快乐编程” 博客,请务必保留此出处http://hqwanghai.blog.51cto.com/5869403/1058710
相关文章推荐
- 数据库获取随机记录
- 各种数据库随机获取N条记录的操作语法
- 数据库获取随机记录
- 随机获取N条数据库记录的四个方法
- 数据库获取随机记录
- 从数据库表中随机获取N条记录的SQL语句
- SQL在各种数据库中获取随机数据记录
- 数据库中随机获取两条记录
- 数据库获取随机记录
- PHP实现在数据库百万条数据中随机获取20条记录的方法
- ORACLE随机获取数据库表的一条记录
- 数据库获取随机记录
- 数据库获取随机记录
- Atitit.并发测试解决方案(2) -----获取随机数据库记录 随机抽取数据 随机排序 原理and实现
- 数据库获取随机记录
- Atitit.并发测试解决方案(2) -----获取随机数据库记录 随机抽取数据 随机排序 原理and实现
- 数据库获取随机记录
- 随机获取数据库表记录行
- 数据库获取随机记录
- 数据库获取随机记录