2009-10-14 11 views
15

Chcę zaznaczyć wszystkie wiersze z tabeli, a następnie przez liczbę losową między 1 do 9:Generowanie liczb losowych w każdym rzędzie w Oracle Query

select t.*, (select dbms_random.value(1,9) num from dual) as RandomNumber 
from myTable t 

ale liczby losowej jest taka sama z rzędu do rzędu, różni się tylko od każdego uruchomienia zapytania. Jak zmienić numer z wiersza na wiersz w tej samej wersji?

+0

Dla jasności, wywołanie 'dbms_random.value()' jest wykonywane tylko raz, ponieważ e 'select', w którym się znajduje, jest oceniane przed zewnętrznym' select'. –

Odpowiedz

25

Coś podobnego?

select t.*, round(dbms_random.value() * 8) + 1 from foo t; 
+2

Składnia dbms_random.value (1,9) jest nadal poprawna.Jest to tylko struktura podkwerendy, która jest zła –

+0

Ah, nie równomierna dystrybucja wartości jednak. –

6

nie potrzebują select … from dual, wystarczy napisać:

SELECT t.*, dbms_random.value(1,9) RandomNumber 
    FROM myTable t 
+0

Ah, świetnie. I w jaki sposób generować losowe liczby całkowite od 1 do 9 zamiast unoszenia się? – Saobi

+0

użyj round ... aaah, too late :( – knittl

14

Na początku myślałem, że to będzie działać:

select DBMS_Random.Value(1,9) output 
from ... 

Jednak to nie generuje równomierny rozkład wartości wyjściowych:

select output, 
     count(*) 
from (
     select round(dbms_random.value(1,9)) output 
     from dual 
     connect by level <= 1000000) 
group by output 
order by 1 

1 62423 
2 125302 
3 125038 
4 125207 
5 124892 
6 124235 
7 124832 
8 125514 
9 62557 

Przyczyny są dość oczywiste, myślę .

Sugeruję użyciu coś takiego:

floor(dbms_random.value(1,10)) 

więc:

select output, 
     count(*) 
from (
     select floor(dbms_random.value(1,10)) output 
     from dual 
     connect by level <= 1000000) 
group by output 
order by 1 

1 111038 
2 110912 
3 111155 
4 111125 
5 111084 
6 111328 
7 110873 
8 111532 
9 110953 
+2

dbms_random.value (1, 10) jest prawdopodobnie bardziej poprawny, ponieważ wynik x jest większy lub równy pierwszemu argumentowi, a mniejszy niż drugi zgodnie z [10.2 dokumentów] (http://docs.oracle.com/cd/B19306_01/appdev.102/ b14258/d_random.htm # i998095) – jswolf19

2

Jeśli wystarczy użyć rundzie wtedy dwa numery końcowe (1 i 9) będą występować rzadziej, aby uzyskać równomierny rozkład liczb całkowitych od 1 do 9, a następnie:

SELECT MOD(Round(DBMS_RANDOM.Value(1, 99)), 9) + 1 FROM DUAL 
+0

Niezły, bardzo przydatny. –

Powiązane problemy