工作中經常用到隨機數,比如隨機抽取獎券,隨機抽取某地區的客戶樣本等。在Oracle中可以非常方便地實現這個功能。
方法1:使用SAMPLE()。
使用sample的語法是:
SAMPLE [ BLOCK ]
(sample_percent)
[ SEED (seed_value) ]
BLOCK: 表示使用隨機塊例舉而不是隨機行例舉。
sample_percent是隨機獲取一張表中記錄的百分比。比如值為10,那就是表中的隨機的百分之10的記錄。值必須大于等于.000001,小于100。
seed表示從哪條記錄返回,類似于預先設定例舉結果,因而每次返回的結果都是固定的。該值必須介于0和4294967295之間。
接下來舉例說明:
SQL> create table zeeno as select * from dba_objects;
Table created.
SQL> select object_name from zeeno sample(10) where rownum=1;
OBJECT_NAME
-------------------------------------------------------------
UET$
SQL> /
OBJECT_NAME
-------------------------------------------------------------
ICOL$
上面的示例表示從表zeeno中隨機抽取10%的記錄,并從中選擇一條記錄。
如果使用seed,則返回固定的集。
1* select object_name from zeeno sample(10) seed(10) where rownum=1
SQL> /
OBJECT_NAME
---------------------------------------------------------------------
PROXY_ROLE_DATA$
SQL> /
OBJECT_NAME
---------------------------------------------------------------------
PROXY_ROLE_DATA$
只所以建臨時表是因為如下原因:
SQL> select object_name from dba_objects sample(10)where rownum=1;
select object_name from dba_objects sample(10)where rownum=1
*
ERROR at line 1:
ORA-01446: cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY,
etc.
方法2:使用DBMS_RANDOM包。
DBMS_RANDOM有兩種主要的使用方法,分別是DBMS_RANDOM.VALUE()和DBMS_RANDOM.RANDOM。
SQL> select dbms_random.value() from dual;
DBMS_RANDOM.VALUE()
-------------------
.638206012
SQL> /
DBMS_RANDOM.VALUE()
-------------------
.312828706
SQL> select dbms_random.value(1,10) from dual
DBMS_RANDOM.VALUE(1,10)
-----------------------
2.49371361
SQL> /
DBMS_RANDOM.VALUE(1,10)
-----------------------
1.6890498
有了隨機數,抽取隨機記錄就是一件非常輕松的事情了:
SQL> select * from (select object_name from zeeno
2 order by dbms_random.random)
3 where rownum=1;
OBJECT_NAME
-------------------------------------------------
DBMS_JAVA_TEST
SQL> /
OBJECT_NAME
-------------------------------------------------
USER_SNAPSHOT_REFRESH_TIMES
SQL> select * from (select object_name from zeeno
1 order by ceil(dbms_random.value(1,3))
2 )
3* where rownum=1
OBJECT_NAME
----------------------------------------------------------
UNDO$
SQL> /
OBJECT_NAME
----------------------------------------------------------
I_USER1
通常情況下我更喜歡使用SAMPLE,因為更加方便。