如何从Oracle数据库中随机获取记录?

问题描述 投票:0回答:11

我需要从 Oracle 数据库中随机选择行。

例如:假设一个表有 100 行,我如何从整个 100 行中随机返回其中的 20 条记录。

oracle select random
11个回答
147
投票
SELECT *
FROM   (
    SELECT *
    FROM   table
    ORDER BY DBMS_RANDOM.RANDOM)
WHERE  rownum < 21;

69
投票

SAMPLE() 不能保证为您提供恰好 20 行,但可能合适(对于大型表,其性能可能明显优于完整查询 + 按随机排序):

SELECT *
FROM   table SAMPLE(20);

注意:这里的

20
是一个近似百分比,而不是所需的行数。在本例中,由于您有 100 行,因此要获得大约 20 行,您需要 20% 的样本。


15
投票
SELECT * FROM table SAMPLE(10) WHERE ROWNUM <= 20;

这更有效,因为它不需要对表进行排序。


10
投票
SELECT column FROM
( SELECT column, dbms_random.value FROM table ORDER BY 2 )
where rownum <= 20;

8
投票

如果表很大,按 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
      )
);

6
投票

综上,介绍了两种方式

1) using order by DBMS_RANDOM.VALUE clause
2) using sample([%]) function

第一种方式的优势在于“正确性”,这意味着如果结果确实存在,你永远不会失败,而第二种方式即使有满足查询条件的案例,也可能得不到结果,因为采样过程中信息会减少。

第二种方式具有“高效”的优势,这意味着您将更快地获得结果并减轻数据库的负载。 DBA 向我发出警告,我使用第一种方式的查询给数据库带来了负载

您可以根据自己的兴趣选择两种方式之一!


5
投票

要随机选择 20 行,我认为您最好选择随机排序的大量行,然后选择该组中的前 20 行。

类似:

Select *
  from (select *
          from table
         order by dbms_random.value) -- you can also use DBMS_RANDOM.RANDOM
 where rownum < 21;

最适用于小表,以避免选择大块数据而丢弃大部分数据。


0
投票

以下是如何从每组中随机选取样本:

SELECT GROUPING_COLUMN, 
       MIN (COLUMN_NAME) KEEP (DENSE_RANK FIRST ORDER BY DBMS_RANDOM.VALUE) 
         AS RANDOM_SAMPLE
FROM TABLE_NAME
GROUP BY GROUPING_COLUMN
ORDER BY GROUPING_COLUMN;

我不确定它的效率如何,但如果你有很多类别和子类别,这似乎可以很好地完成工作。


0
投票

-- 问:如何从表中查找随机 50% 的记录?

当我们想要百分比随机数据时

选择* 从 ( 选择 * FROM 表名 按 DBMS_RANDOM.RANDOM 排序) 哪里 rownum <= (select count(*) from table_name) * 50/100;


0
投票

从 Oracle 12c 开始,我们可以使用

FETCH
语句来实现这一点

SELECT *
FROM  table
ORDER BY DBMS_RANDOM.RANDOM
FETCH FIRST 20 ROWS ONLY

-1
投票

从中选择* (SELECT * FROM emp ORDER BY DBMS_RANDOM.RANDOM )哪里
行号 <= 1 ;

© www.soinside.com 2019 - 2024. All rights reserved.