2009-10-14 5 views
15

Ich möchte alle Zeilen einer Tabelle durch eine Zufallszahl zwischen 1 bis 9 gefolgt auszuwählen:Generierung von Zufallszahlen in jeder Zeile in Oracle Abfrage

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

Aber der Zufallszahl ist das gleiche von Zeile zu Zeile, nur unterschiedlich von jedem Lauf der Abfrage. Wie ändere ich die Nummer in derselben Ausführung von Zeile zu Zeile?

+0

Nur um klar zu sein, der Aufruf 'dbms_random.value()' wird nur einmal ausgeführt, seit th e 'select' es wird vor dem äußeren' select' ausgewertet. –

Antwort

25

So etwas?

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

Die dbms_random.value (1,9) -Syntax ist immer noch korrekt. Es ist nur die Unterabfrage-Struktur, die falsch ist –

+0

Ah, nicht eine gleichmäßige Verteilung der Werte obwohl. –

6

Sie brauchen nicht zu einem select … from dual, schreiben Sie einfach:

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

Ah, großartig. Und wie erzeuge ich zufällige Ganzzahlen von 1 bis 9 anstatt zu schweben? – Saobi

+0

Verwenden Sie Runde ... aaah, zu spät :( – knittl

14

Zuerst dachte ich, dass dies funktionieren würde:

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

Dies ist jedoch eine gleichmäßige Verteilung der Ausgangswerte nicht erzeugen:

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 

Die Gründe dafür sind ziemlich offensichtlich, dass ich denke, .

Ich würde vorschlagen, mit so etwas wie:

floor(dbms_random.value(1,10)) 

Daraus folgt:

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) ist wahrscheinlich korrekter, da das Ergebnis x größer als oder gleich dem ersten Argument und weniger als das zweite gemäß der [10.2 Dokumente] ist (http://docs.oracle.com/cd/B19306_01/appdev.102/ b14258/d_random.htm # i998095) – jswolf19

2

Wenn Sie nur rund verwenden dann die beiden Endziffern (1 und 9) werden weniger häufig auftreten, zu erhalten eine gerade Verteilung von ganzen Zahlen zwischen 1 und 9 dann:

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

Schön, sehr nützlich, Tnks –