【问题标题】:Generate random value from a list of values with even distribution in Oracle从 Oracle 中均匀分布的值列表生成随机值
【发布时间】:2020-11-05 20:15:47
【问题描述】:

我正在尝试从有效值列表 [1,2,3,4,5,9] 中生成一个随机值。如果我运行我的函数 10 次,则有 2 个值永远不会出现。我需要列表中的每个值都出现在我的示例中。我怎样才能确保这一点?均匀分布会很好,但每个值至少有几行。

select random_code
        from (
                with temp_code_table as (
                     select '1' as random_code from dual union
                     select '2' as random_code from dual union
                     select '3' as random_code from dual union
                     select '4' as random_code from dual union
                     select '5' as random_code from dual union
                     select '9' as random_code from dual)
                     select random_code from temp_code_table order by dbms_random.value)
       where rownum = 1;

我在一个函数中运行上面的SQL,它会检查生成的随机码是否与原始值不同。

编辑:不确定下面帖子中的答案是否能帮助我实现我想要的。

Generating Random Value using CASE

关于如何实现这一点的任何建议?

【问题讨论】:

  • 。 .运行代码 20 次或 100 次。

标签: sql oracle


【解决方案1】:

“一个随机数”和“至少一个”不能组合使用。随机的定义是你不知道你会得到什么……掷骰子 10 次。你确定你至少会扔掉所有的面吗?不。 因此,要解决您的问题,您可以先选择其中一个 - 这样您就已经有了这些,然后用从集合中随机选择的数字填充其余部分。

with temp_code_table (nr) as 
(
  SELECT '1' FROM dual UNION
  SELECT '2' FROM dual UNION
  SELECT '3' FROM dual UNION
  SELECT '4' FROM dual UNION
  SELECT '5' FROM dual UNION
  SELECT '9' FROM dual
)
-- now select one of each. order doesn't matter, we're doing that at the end
, one_of_each AS
(
  SELECT nr FROM temp_code_table 
)
-- ok we got at least one of each. Now fill up the rest with randoms
-- generate a list of hundred random values 1,2,3,4,5,9 (100 is chosen randomly)
, hundred_random AS
( 
  SELECT CASE round(dbms_random.value(1,6)) 
              WHEN 1 THEN '1'
              WHEN 2 THEN '2'
              WHEN 3 THEN '3' 
              WHEN 4 THEN '4'
              WHEN 5 THEN '5'
              WHEN 6 THEN '9' 
         END AS nr
  FROM DUAL connect by LEVEL < 101
)
-- select 4 out of those.
, four_more (nr) AS
( 
  SELECT nr FROM hundred_random WHERE rownum < 5
)
-- put it all together
, ten_rows AS
(
  SELECT nr FROM one_of_each
  UNION ALL
  SELECT nr FROM four_more
)
-- and shuffle...
SELECT nr FROM ten_rows order by dbms_random.value
;

“temp_code_table”cte 正好生成 6 行。这样,您在集合中的每个数字中至少有一个。 "hundred_random" cte 对随机数使用 case 语句,这将生成集合的单个随机值。然后使用CONNECT BY LEVEL 运行 100 次。在这 100 人中,挑选了 4 人。这 4 个都可能是 1 - 这是随机的,不能保证你有不同的数字。 最后我们将 temp_code_table cte 的 6 行和four_more 的 4 行联合起来,并随机排序。

【讨论】:

  • 你能告诉我'case'和'order by dbms.random'之间的分布吗?
  • 编辑了我的答案。这些是 CTE 的公用表表达式。您可以拆分此语句并单独运行每个 cte。我建议你这样做并观察它们是如何工作的——这是最好的学习方式。
猜你喜欢
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 2013-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多