Oracle学习笔记之数据库获取随机的n条记录

        最近在做公司的车联网服务系统,碰到一个需求,需要从数据库中获取随机的n条记录。我参照了《SQL COOKBOOK》中提供的解决方案,现记笔记如下,分享给大家。

解决方案

        使用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行时,会发生下面的操作:

  1. Oracle执行查询
  2. Oracle获取第1个符合条件的行,将它叫做第1行。
  3. 有5行了吗?如果没有,那么Oracle就再返回行,因为它要满足行号小于等于5的条件,如果到了5行,那么,Oracle将不再返回行。
  4. Oracle获取下一行,并递增行号(从2,到3,再到4,等等)。
  5. 返回第3步。

       可以看到,Oracle的ROWNUM数值是在获取每行之后才赋予的,这非常重要,是一个关键点。比如说,许多Oracle开发人员想通过指定ROWNUM=5来返回第5行,这是错误的做法。下面说明使用ROWNUM=5会发生什么:

  1. Oracle执行查询。
  2. Oracle获取第一个符合条件的行,将它叫做第1行。
  3. 有5行了吗?如果没有,那么Oracle就丢弃这些行,因为它不满足条件。如果到了5行,那么,Oracle就返回该行。但是,答案是,永远也不会有"到了5行"的情况发生。
  4. Oracle获取下一行,这是第一行。原因是,从查询中返回的必须是编号为1的行。
  5. 转向第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

 

你可能感兴趣的:(oracle,数据库,分页)