我需要从Oracle数据库中随机选择行。
例如:假设一个表有100行,我如何从整个100行中随机返回20条记录。
Answers:
SELECT *
FROM (
SELECT *
FROM table
ORDER BY DBMS_RANDOM.RANDOM)
WHERE rownum < 21;
不能保证SAMPLE()会准确地为您提供20行,但可能是合适的(对于大型表,它的性能可能比完全查询+按随机排序好得多):
SELECT *
FROM table SAMPLE(20);
注意:20
这是一个近似百分比,而不是所需的行数。在这种情况下,由于您有100行,因此要获得约20行,您需要提供20%的样本。
要随机选择20行,我认为最好选择随机排列的行并选择该行的前20行。
就像是:
Select *
from (select *
from table
order by dbms_random.value) -- you can also use DBMS_RANDOM.RANDOM
where rownum < 21;
最适合用于小表,以避免选择大块数据而只是丢弃大部分数据。
在大型表的情况下,按dbms_random.value进行排序的标准方法无效,因为您需要扫描整个表,而dbms_random.value是相当慢的功能,需要上下文切换。对于这种情况,还有3种其他方法:
1:使用sample
子句:
例如:
select *
from s1 sample block(1)
order by dbms_random.value
fetch first 1 rows only
例如,获得所有块的1%,然后对它们进行随机排序,仅返回1行。
2:如果您在具有正态分布的列上具有索引/主键可以获取最小值和最大值,获取该范围内的随机值,并获取第一行的值大于或等于随机生成的值。
例:
--big table with 1 mln rows with primary key on ID with normal distribution:
Create table s1(id primary key,padding) as
select level, rpad('x',100,'x')
from dual
connect by level<=1e6;
select *
from s1
where id>=(select
dbms_random.value(
(select min(id) from s1),
(select max(id) from s1)
)
from dual)
order by id
fetch first 1 rows only;
3:获取随机表块,生成rowid并通过该rowid从表中获取行:
select *
from s1
where rowid = (
select
DBMS_ROWID.ROWID_CREATE (
1,
objd,
file#,
block#,
1)
from
(
select/*+ rule */ file#,block#,objd
from v$bh b
where b.objd in (select o.data_object_id from user_objects o where object_name='S1' /* table_name */)
order by dbms_random.value
fetch first 1 rows only
)
);
表
SELECT * FROM
(
SELECT column_name FROM table_name
ORDER BY dbms_random.value
)
WHERE rownum = 1;