【问题标题】:generate random numbers in pl/sql without duplicates?在 pl/sql 中生成没有重复的随机数?
【发布时间】:2016-11-12 12:51:57
【问题描述】:

我需要编写一个程序来生成从 x 到 y 范围内的 n 个唯一数字?不允许重复。我知道可以使用 dbms_random.value(x, y) 生成随机数,但值是重复的。

【问题讨论】:

  • 您需要提供 n 的上限。如果 n 太大,问题可能没有解决方案(机器中可以表示的数字的数量总是有限的,因此如果 n 大于该数字,则没有解决方案)。如果 n 仍然非常大,但在第一种意义上不是“太大”,那么问题可能是可以解决的,但时间估计为 9,000 年。那么:为什么需要写一个PROCEDURE?这可以在纯 SQL 中完成。 “过程”是字面意思 - 这是用于 PL/SQL 中的一个类,还是编写过程?还是一个简单的 SQL 解决方案就足够了?

标签: sql database oracle plsql


【解决方案1】:

好吧,首先 - 如果必须生成没有重复的数字,那么它们就不是真正随机的。

因为这听起来像是课堂作业,所以我不打算为您编写代码。但是,您可以尝试以下方法:

创建一个表 UNIQUE_NUMBERS,其中有一列名为 UNIQUE_NUMBER,类型为 NUMBER,该列被限制为唯一。在您的函数中,生成您喜欢的数字,然后将其插入 UNIQUE_NUMBERS。如果插入正确,一切都很好,则该值是唯一的,您的函数可以提交插入并返回该值。如果出现异常,则表示该值已经存在,但没有插入,您需要循环返回并随机生成另一个数字。

祝你好运。

【讨论】:

    【解决方案2】:

    您可以使用 CTE 生成从 x 到 y 的数字。然后你可以随机排序:

    with n as (
          select level as n
          from dual
          connect by level <= ("x" - "y" + 1)
         ),
         rand_n as (
          select n + "x" - 1
          from n
          order by dbms_random.random
         )
    select *
    from rand_n;
    

    当然,这是假设“x”和“y”之间的差异不是很大。

    【讨论】:

    • ??您的意思是在外部查询中有一个限制过滤器,可能类似于rownum &lt;= n?所写的查询将返回xy 之间的所有数字。 (此外,OP 具有变量 n 也无济于事,并且您还选择命名一个表和一个列 n。)
    【解决方案3】:

    一种方法是生成多于n 的数字(例如,多 10%)。在1.1 * n 数字中具有少于n 不同数字的几率可能非常低,在遇到这种情况之前的预期时间比太阳系的寿命更长(如果n 相当小)。

    然后,对于 1.1 * n 随机数,您完全期望其中至少 n 将是不同的,您可以选择 distinct 并按 rownum 过滤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 2021-03-31
      相关资源
      最近更新 更多