在 SQL 或 PL/SQL 中以 2:1 的比例生成 1 到 2 之间的 6 个数字

发布于 2024-11-02 22:42:14 字数 317 浏览 0 评论 0原文

我如何生成 1 和 2 之间的 6 个数字,其中 4 个数字为 1,另外 2 个数字为 2,按随机顺序,即

结果

1
2
1
1
1
2

,也可以采用不同的比例,即 3:2:1,对于 1 到 3 之间的数字,对于 12 个数字,

结果

1
1
2
3
1
2
1
3
1
1
3
3 个

结果不必按此顺序,而是按上述 oracle SQL 或 PL/SQL 中的比率

how can i generate 6 numbers between 1 and 2 where 4 of the numbers will be 1 and the other 2 will be 2 in a random order i.e.

results

1
2
1
1
1
2

and also in a different ratio i.e. 3:2:1 for numbers between 1 and 3 for 12 numbers

i.e.

results

1
1
2
3
1
2
1
3
1
1
3
3

results don't have to be in this order but in the ratios as above in oracle SQL or PL/SQL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天邊彩虹 2024-11-09 22:42:15

为了获得完美的比率,你可以这样做 - 生成所有数字,然后按随机顺序排序:

SELECT r
FROM   (SELECT CASE
               WHEN ROWNUM <=4 THEN 1
               ELSE 2
               END AS r
        FROM DUAL
        CONNECT BY LEVEL <= 6)
ORDER BY DBMS_RANDOM.value;

R                      
---------------------- 
2                      
1                      
1                      
2                      
1                      
1                      

To get the ratios perfect you could do something like this - generate all the numbers, then sort in random order:

SELECT r
FROM   (SELECT CASE
               WHEN ROWNUM <=4 THEN 1
               ELSE 2
               END AS r
        FROM DUAL
        CONNECT BY LEVEL <= 6)
ORDER BY DBMS_RANDOM.value;

R                      
---------------------- 
2                      
1                      
1                      
2                      
1                      
1                      
无所的.畏惧 2024-11-09 22:42:15

我认为这适用于直接 SQL;它的效率极其低下,而 PL/SQL 的效率可能要低一些。它也是完全静态的;不同的比率需要选择不同数量的值。

select value
  from (
       select mod(value, 2) + 1 as value, 
              row_number() over (partition by 
                                   case mod(value, 2) = 1 
                                     then 1 
                                     else 0 
                                   end) as twos_row,
              row_number() over (partition by 
                                   case mod(value, 2) = 0
                                     then 1 
                                     else 0 
                                   end) as ones_row
         from (select dbms_crypto.randominteger as value
                 from dba_objects
                order by object_id
              )
       )
 where twos_rows <= 2
    or ones_rows <= 4

最里面的选择抓取一大堆随机数。下一个查询通过修改先前的随机值来确定该随机值是 2 还是 1。最后一层嵌套只是在返回正确数量的该类型行后过滤掉所有行。

这是未经测试且脆弱的。如果您需要一个可靠且高性能的解决方案,我建议您使用 PL/SQL,您可以

  • 循环
  • 选取随机数,
  • 确定它们适合的值集中的哪个分区,
  • 未满足要求,则保留它们
  • 如果该分区在退出时 所有分区均已满足。

I think this will work in straight SQL; it's horrifically inefficient, and a PL/SQL one might be less so. It's also completely static; differing ratios call for a different number of values selected.

select value
  from (
       select mod(value, 2) + 1 as value, 
              row_number() over (partition by 
                                   case mod(value, 2) = 1 
                                     then 1 
                                     else 0 
                                   end) as twos_row,
              row_number() over (partition by 
                                   case mod(value, 2) = 0
                                     then 1 
                                     else 0 
                                   end) as ones_row
         from (select dbms_crypto.randominteger as value
                 from dba_objects
                order by object_id
              )
       )
 where twos_rows <= 2
    or ones_rows <= 4

The inner-most select grabs a big stack of random numbers. The next query out determines whether that random value would be a 2 or a 1 by mod'ing the earlier random value. The last level of nesting just filters out all the rows after the correct number of that type of row has been returned.

This is untested and fragile. If you need a solution that's reliable and performance, I'd recommend PL/SQL, where you

  • loop
  • pick off random numbers
  • determine what partition in your set of values they'd fit into
  • keep them if that partition hasn't been satisfied
  • exit when all partitions have been satisfied.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文