2017-02-20 65 views
0

我有以下代码:生成只使用一个随机列表中选择

create table test 
(
    name varchar2(20 byte) 
); 

insert into test values ('Fred'); 
insert into test values ('Wilma'); 
insert into test values ('Betty'); 
insert into test values ('Barny'); 

commit; 

select * from test order by dbms_random.random; 

当然的select语句将创建在这种情况下,正是4项随机列表。有没有办法改变select语句,以便列表可以扩展到多于或少于4个条目而不需要使用PL?

+0

你想从表测试中选择X次随机行吗? –

+0

是 - 从表test中检索包含随机行的X行 –

+1

'select t。* from test t,(select rownum rn from double connect by level <= 2)a order by dbms_random.random;'生成8行行= 4 *级别2 = 8)。 – JSapkota

回答

2

您可以使用自交叉连接来平均可用的行数,将结果随机排序,并获取第一个X行;假设X低于行数的平方,例如,四个源行有16个结果形成交叉连接,并在这个例子中X为10,你得到你想要的东西:

select * from (
    select t1.name from test t1 
    cross join test t2 
    order by dbms_random.value 
) 
where rownum <= 10; 

NAME     
-------------------- 
Betty 
Betty 
Fred 
Betty 
Wilma 
Betty 
Fred 
Wilma 
Barny 
Barny 

10 rows selected. 

你可以做同样的事情用一个分层查询生成额外行:

select * from (
    select * from test 
    connect by level < 3 
    order by dbms_random.value 
) 
where rownum <= 10; 

NAME     
-------------------- 
Fred 
Fred 
Barny 
Wilma 
Betty 
Betty 
Wilma 
Betty 
Wilma 
Wilma 

10 rows selected. 

每次查询运行时,10(X)行都不相同。

如果X较大,则可以增加层数。使用level < 3,内部查询生成20行;与level < 4你得到84等。

如果你的源表很大,你可能想要更严格,例如,添加prior子句,所以行数(以及所需的内存量)不会失控。从你简化的例子中,很难准确猜出你需要什么限制。你可以,例如,假设“名”其实是一个独特的密钥,这样做:

select * from (
    select * from test 
    connect by level < 10 
    and prior name = name 
    and prior dbms_random.value is not null 
    order by dbms_random.value 
) 
where rownum <= 10; 

内的查询现在只得到36行与level < 10限制。您需要测试真实的数据量并调整合理的结果和性能。