在 Oracle 中选择随机行

Posted

技术标签:

【中文标题】在 Oracle 中选择随机行【英文标题】:Selecting a Random Row in Oracle 【发布时间】:2017-01-03 17:29:08 【问题描述】:

我需要从一个表中随机选择值,例如tableA.a_idVARCHAR2,并使用该值插入另一个表。例如,假设需要将三列插入到 100 行 tableX(一个序列号,一个 100 到 999 之间的随机数,以及 tableA.a_id 的值)中:

insert into tableX
select
    rownum,
    dbms_random.value(100,999), 0),
    (select a_id from 
    (
      SELECT a_id 
      FROM tableA
      ORDER BY dbms_random.value
    )
    where rownum = 1)
from
   (select level from dual connect by level <= 100);

但是,它不是为每一行从tableA.a_id 中选择一个随机行,而是为所有行选择相同的值,例如:

1 129 A-ID-48
2 849 A-ID-48
3 367 A-ID-48

但是,如果我重复执行子查询,我每次都会得到一个新值(原因很明显),例如:

select a_id from 
    (
      SELECT a_id 
      FROM tableA
      ORDER BY dbms_random.value
    )
where rownum = 1;

每次执行后的结果:

A-ID-7
A-ID-48
A-ID-74

如何更改原始查询,或者为此提出一个新查询,将每个插入行从tableAa_id 列插入到目标表中的随机行?期望结果:

1 129 A-ID-7
2 849 A-ID-48
3 367 A-ID-74

更新 1

基于mathguy answer,我更新了单个表选择的查询:

insert into tableX
select
    rownum,
    round(dbms_random.value(100,999), 0),
    a_id
from
    (
      select 
        round(dbms_random.value(1, (select count(*) from tableA)), 0) tableX_rand_num
      from tableX
    ) x
join 
    (
      select
        a_id, 
        dbms_random.value() rnd,
        rownum tableA_rownum
      from tableA
      order by rnd
    ) a
on x.tableX_rand_num = a.tableA_rownum
where rownum <= 100;

限制:使用此方法插入的行数不会独立于父表中可用的记录数 (tableX)。换句话说,您只能插入与tableX 中可用的总行数一样多的记录。例如如果tableX 有 200 条记录,而您希望插入 1000 条,则上面的查询最多只能插入 200 行。

【问题讨论】:

【参考方案1】:

进行内部查询:

select a_id, dbms_random.value() rnd from tableA order by rnd

然后在外部查询中一次性选择 100 行,rownum &lt;= 100

像这样:

insert into tableX
select
    rownum,
    round(dbms_random.value(100,999), 0),
    a_id
from
    (
      SELECT a_id, dbms_random.value() rnd
      FROM tableA
      ORDER BY rnd
    )
where rownum <= 100;

【讨论】:

我不太符合你的逻辑。我需要替换哪个内部查询?我不需要where rownum = 1 进行第一个内部查询来只带回一条记录吗? 将完整查询添加到答案更容易。请看上面。我加回了round(,您似乎不小心删除了它。 我认为这些更改没有通过。 :) 注意:这将返回 100 个不同的行(这不完全是“随机的”)。如果您希望它们真正随机,也可以这样做,但人们通常希望绘制不同的行。 好的,但是如果有额外的表怎么办,例如tableY.y_id,查询需要从中检索随机行吗?就像需要将主键随机插入父表的多个子表一样?此外,本例中的tableAtableX 小得多,因此预计会出现来自tableA.a_id 的重复项(与tableY.y_id 相同)。

以上是关于在 Oracle 中选择随机行的主要内容,如果未能解决你的问题,请参考以下文章

从 SQL Server 表中选择 n 个随机行

从巨大的 CSV 文件中读取随机行

从 sqlite 表中选择随机行

Pandas 数据框中的随机行选择

如何从 SQL 数据库表中选择随机行? [复制]

从mysql中的大表中快速选择随机行