【问题标题】:Random records for a row一行的随机记录
【发布时间】:2021-06-01 22:41:26
【问题描述】:

我有下表 strvals() 和数据。我希望从 strval() 表中随机选择 2 行并循环填充表 S1。

我想要这样的东西

Create table s1(id primary key,strval1, strval2) as 
   select level,random_rec(strvals), random_rec(strvals) 
   from dual 
   connect by level<=10;

需要注意的是,每行的 strval1 列必须不同 THEN strval2。

Valid output
1, 'AAAA', 'BBBB'
2, 'CCCC', 'BBBB'
3, 'CCCC', 'AAAA'

无效

1, 'AAAA', 'AAAA'

Create table strvals(
  strval varchar2(4),
  constraint pk_strval primary key (strval)   
);

insert into strvals 
values(  
 'AAAA'   
);

insert into strvals 
values(  
 'BBBB'   
);

insert into strvals 
values(  
 'CCCC'   
);

【问题讨论】:

  • 谢谢我点击了代码标签,并认为这会格式化代码。我需要 或 [] 标记来格式化

标签: sql oracle random


【解决方案1】:

从表中获取随机字符串可能很棘手。一种方法是使用相关子查询——相关子句确保子查询不会“优化”为只运行一次。

所以,这里有一种方法:

select id, strval,
       (select s2.strval
        from strvals s2
        where s2.strval <> x.strval and x.id > 0
        order by dbms_random.random fetch first 1 row only
       ) as strval2
from (select id,
             (select strval
              from strvals
              where x.id > 0
              order by dbms_random.random fetch first 1 row only
             ) as strval
     from (select level as id
           from dual 
           connect by level < 25
          ) x
    ) x;

here 是一个数据库小提琴。

【讨论】:

  • 完美!!感谢您的帮助和专业知识
  • @Beefstu 。 . .如果这回答了您的问题,您可以接受答案。
  • “谢谢”在评论中,但甚至没有对答案投赞成票:) 所以我要投赞成票
【解决方案2】:

为了在多行的情况下减少一些缓慢的 dbms_random.value,我建议使用这种技术:

with 
 rand as (select row_number()over(order by dbms_random.value()) n,strval from strvals)
,cnt as (select count(*) m from rand)
,generator as (select level id,  ceil(dbms_random.value()*cnt.m) rnd from cnt connect by level<=10)
select generator.id, rand.strval
from generator
     join rand on rand.n=generator.rnd;

如你所见,我按dbms_random.value(rand视图)对表strvals排序一次,所以每一行都有自己的随机整数,然后我计算它们以获得最大N。然后我计算随机数N 为每个生成的行,因此我们可以使用哈希连接加入 rand 视图。

更新:对于 2 个字符串:DBFiddle

with 
 rand as (select row_number()over(order by dbms_random.value()) n,strval from strvals)
,cnt as (select count(*) m from rand)
,generator as (
    select
       level id,
       ceil(dbms_random.value()*cnt.m) rnd1,
       ceil(dbms_random.value()*cnt.m) rnd2
    from cnt connect by level<=10
 )
select
   generator.id,
   rnd1.strval,
   rnd2.strval
from generator
     join rand rnd1 on rnd1.n=generator.rnd1
     join rand rnd2 on rnd2.n=generator.rnd2;

Update2:现在有 2 个字符串:DBFiddle

with 
 rand as (
    select
        row_number()over(order by dbms_random.value()) n
        ,s1.strval strval1
        ,s2.strval strval2
    from strvals s1
         join strvals s2
            on s1.strval!=s2.strval
 )
,cnt as (select count(*) m from rand)
,generator as (
    select
       level id,
       ceil(dbms_random.value()*cnt.m) rnd
    from cnt connect by level<=10
 )
select
   generator.id,
   rand.strval1,
   rand.strval2
from generator
     join rand on rand.n=generator.rnd
order by 1
;

【讨论】:

  • 感谢您的回复和专业知识。我的要求是有 2 个字符串作为输出的一部分,即 1,'AAAA', 'BBBB' 2, 'CCCC', 'BBBB' 3, 'CCCC', 'AAAA'
  • 啊,好的,完成 - 请查看更新后的答案
  • 啊,抱歉,我错过了另一个要求 - 有不同的 strvals...不确定我的方法是否对此有效...
  • @Beefstu 好的,用 2 个 strvals 完成。请查看最新更新
  • 感谢您的帮助和雄辩的解决方案。希望我能自己完成剩下的工作。
猜你喜欢
  • 2014-08-04
  • 2020-08-31
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多