Necesito un número aleatorio diferente para cada fila de mi tabla. El siguiente código aparentemente obvio usa el mismo valor aleatorio para cada fila.
SELECT table_name, RAND() magic_number
FROM information_schema.tables
Me gustaría obtener un INT o un FLOTADOR de esto. El resto de la historia es que voy a usar este número aleatorio para crear un desplazamiento de fecha aleatorio a partir de una fecha conocida, por ejemplo, un desplazamiento de 1-14 días desde una fecha de inicio.
Esto es para Microsoft SQL Server 2000.
sql-server
tsql
sql-server-2000
MatthewMartin
fuente
fuente
Respuestas:
Eche un vistazo a SQL Server: establezca números aleatorios basados que tienen una explicación muy detallada.
Para resumir, el siguiente código genera un número aleatorio entre 0 y 13 inclusive con una distribución uniforme:
Para cambiar su rango, simplemente cambie el número al final de la expresión. Tenga mucho cuidado si necesita un rango que incluya números positivos y negativos. Si lo haces mal, es posible contar dos veces el número 0.
Una pequeña advertencia para las matemáticas en la sala: hay un sesgo muy leve en este código.
CHECKSUM()
da como resultado números que son uniformes en todo el rango del tipo de datos sql Int, o al menos tan cerca como pueden mostrar mis pruebas (del editor). Sin embargo, habrá algún sesgo cuando CHECKSUM () produzca un número en el extremo superior de ese rango. Cada vez que obtenga un número entre el número entero máximo posible y el último múltiplo exacto del tamaño de su rango deseado (14 en este caso) antes de ese número entero máximo, esos resultados se verán favorecidos sobre la porción restante de su rango que no se puede producir a partir de ese último múltiplo de 14.Como ejemplo, imagine que todo el rango del tipo Int es solo 19. 19 es el mayor entero posible que puede tener. Cuando CHECKSUM () da como resultado 14-19, estos corresponden a los resultados 0-5. Esos números serían muy favorecidos sobre 6-13, porque CHECKSUM () tiene el doble de probabilidades de generarlos. Es más fácil demostrar esto visualmente. A continuación se muestra todo el conjunto de resultados posibles para nuestro rango entero imaginario:
Puede ver aquí que hay más posibilidades de producir algunos números que otros: sesgo. Afortunadamente, el rango real del tipo Int es mucho mayor ... tanto que en la mayoría de los casos el sesgo es casi indetectable. Sin embargo, es algo a tener en cuenta si alguna vez te encuentras haciendo esto por un código de seguridad serio.
fuente
Cuando se llama varias veces en un solo lote, rand () devuelve el mismo número.
Sugeriría usar convert (
varbinary
,newid()
) como argumento inicial:newid()
se garantiza que devolverá un valor diferente cada vez que se llame, incluso dentro del mismo lote, por lo que usarlo como semilla hará que rand () otorgue un valor diferente cada vez.Editado para obtener un número entero aleatorio del 1 al 14.
fuente
Lo anterior generará un número (pseudo-) aleatorio entre 0 y 1, exclusivo. Si se usa en una selección, debido a que el valor inicial cambia para cada fila, generará un nuevo número aleatorio para cada fila (sin embargo, no se garantiza que genere un número único por fila).
Ejemplo cuando se combina con un límite superior de 10 (produce números del 1 al 10):
Documentación de Transact-SQL:
CAST()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sqlRAND()
: http://msdn.microsoft.com/en-us/library/ms177610.aspxCHECKSUM()
: http://msdn.microsoft.com/en-us/library/ms189788.aspxNEWID()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sqlfuente
Generación de números aleatorios entre 1000 y 9999 inclusive:
"+1": para incluir valores de límite superior (9999 para el ejemplo anterior)
fuente
FLOOR(RAND(CHECKSUM(NEWID()))*(10000-1000)+1000)
Responde la pregunta anterior, pero esta respuesta no se ha proporcionado previamente, y con suerte esto será útil para alguien que encuentre estos resultados a través de un motor de búsqueda.
Con SQL Server 2008, se ha introducido una nueva función
CRYPT_GEN_RANDOM(8)
, que utiliza CryptoAPI para producir un número aleatorio criptográficamente fuerte, devuelto comoVARBINARY(8000)
. Aquí está la página de documentación: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlEntonces, para obtener un número aleatorio, simplemente puede llamar a la función y convertirla al tipo necesario:
o para obtener un valor
float
entre -1 y +1, podría hacer algo como esto:fuente
La función Rand () generará el mismo número aleatorio, si se usa en una tabla SELECT query. Lo mismo se aplica si usa una semilla para la función Rand. Una forma alternativa de hacerlo es usar esto:
Obtuve la información de aquí , lo que explica muy bien el problema.
fuente
¿Tiene un valor entero en cada fila que podría pasar como semilla a la función RAND?
Para obtener un número entero entre 1 y 14, creo que esto funcionaría:
fuente
RAND(<seed>)
que no parece ser muy aleatorio para cambios menores en<seed>
. Por ejemplo, hice una prueba rápida: dejé<seed>
ser 184380, 184383, 184386, y losRAND(<seed>)
valores correspondientes fueron: 0.14912, 0.14917, 0.14923.RAND(<seed>)*100000) - FLOOR(RAND(<seed>)*100000)
Si necesita preservar su semilla para que genere los "mismos" datos aleatorios cada vez, puede hacer lo siguiente:
1. Cree una vista que devuelva select rand ()
2. Cree un UDF que seleccione el valor de la vista.
3. Antes de seleccionar sus datos, siembre la función rand () y luego use el UDF en su instrucción select.
fuente
intente usar un valor de inicialización en RAND (seedInt). RAND () solo se ejecutará una vez por declaración, por eso ves el mismo número cada vez.
fuente
RIGHT(CONVERT(BIGINT, RAND(RecNo) * 1000000000000), 2)
(nota: estoy viendoRIGHT
implícitamente convertirBIGINT
aCHAR
, pero para ser riguroso, tendrías otroCONVERT
allí).Si no necesita que sea un número entero, pero cualquier identificador único aleatorio, puede usar
newid()
fuente
Debería llamar a RAND () para cada fila. Aquí hay un buen ejemplo.
https://web.archive.org/web/20090216200320/http://dotnet.org.za/calmyourself/archive/2007/04/13/sql-rand-trap-same-value-per-row.aspx
fuente
RAND()
una vista, pone unaSELECT
de esa vista en una función, y luego llama a la función desde cualquier lugar. Inteligente.Aquí el número aleatorio vendrá entre 20 y 30.
round
dará un máximo de dos decimales.Si quieres números negativos puedes hacerlo con
Entonces el valor mínimo será -60 y el máximo será -50.
fuente
Es tan fácil como:
Y esto pondrá un número aleatorio entre 0-99 en una tabla:
fuente
El problema que a veces tengo con la "Respuesta" seleccionada es que la distribución no siempre es pareja. Si necesita una distribución muy uniforme de 1 a 14 al azar entre muchas filas, puede hacer algo como esto (mi base de datos tiene 511 tablas, por lo que funciona. Si tiene menos filas que el intervalo de números aleatorios, esto no funciona bien):
Esto hace lo contrario de las soluciones aleatorias normales en el sentido de que mantiene los números secuenciados y aleatoriza la otra columna.
Recuerde, tengo 511 tablas en mi base de datos (que es pertinente solo b / c que estamos seleccionando desde el esquema de información). Si tomo la consulta anterior y la pongo en una tabla temporal #X, y luego ejecuto esta consulta en los datos resultantes:
Obtengo este resultado, que me muestra que mi número aleatorio se distribuye MUY uniformemente entre las muchas filas:
fuente
siempre ha trabajado para mi
fuente
Use newid ()
o posiblemente esto
fuente
fuente
Prueba esto:
¿Dónde
a
está el número inferior yb
es el número superior?fuente
Número entre 1 y 10.
fuente