2017-02-20 68 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限制。您需要測試真實的數據量並調整合理的結果和性能。