2009-10-14 25 views
15

Quiero seleccionar todas las filas de una tabla seguido por un número aleatorio entre 1 y 9:Generación de Números Aleatorios En cada fila de consultas de Oracle

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

Pero el número aleatorio es el mismo de fila en fila, solo diferente de cada ejecución de la consulta. ¿Cómo hago que el número sea diferente de una fila a otra en la misma ejecución?

+0

Para que quede claro, la llamada 'dbms_random.value()' solo se ejecuta una vez, ya que th e 'select' está en se evalúa antes del' select' externo. –

Respuesta

25

Algo así?

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

La sintaxis dbms_random.value (1,9) sigue siendo correcta. Es solo la estructura de la subconsulta incorrecta –

+0

Ah, aunque no hay una distribución de valores uniforme. –

6

que no es necesario un select … from dual, acaba de escribir:

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

Ah, genial. ¿Y cómo puedo generar enteros aleatorios de 1 a 9 en lugar de flotantes? – Saobi

+0

use round ... aaah, too late :( – knittl

14

Al principio pensé que esto funcionaría:

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

Sin embargo, esto no genera una distribución uniforme de los valores de salida:

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 

Las razones son bastante obvias pienso .

yo sugeriría usar algo como:

floor(dbms_random.value(1,10)) 

Por lo tanto:

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) es probablemente más correcto ya que el resultado x es mayor o igual que el primer argumento y menor que el segundo de acuerdo con [10.2 documentos] (http://docs.oracle.com/cd/B19306_01/appdev.102/ b14258/d_random.htm # i998095) – jswolf19

2

Si sólo utiliza ronda luego los dos números de los extremos (1 y 9) se producirá con menos frecuencia, para obtener una distribución uniforme de enteros entre 1 y 9 luego:

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

Bueno, muy útil. –

Cuestiones relacionadas