sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo genero un número aleatorio para cada fila en una selección de T-SQL?

Eche un vistazo a SQL Server:establecer números aleatorios basados ​​en 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:

ABS(CHECKSUM(NewId())) % 14

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 hace mal, es posible contar dos veces el número 0.

Una pequeña advertencia para los fanáticos de las matemáticas en la sala:hay un ligero sesgo 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 mi prueba (el editor) puede mostrar. Sin embargo, habrá algún sesgo cuando CHECKSUM() produzca un número en el extremo superior de ese rango. Cada vez que obtiene 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 ven 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 el rango completo del tipo Int es solo 19. 19 es el entero más grande posible que puede contener. Cuando CHECKSUM() da como resultado 14-19, estos corresponden a los resultados 0-5. Esos números serían muy pesados favorecido 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 el conjunto completo de resultados posibles para nuestro rango de enteros imaginarios:

Checksum Integer: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Range Result:     0 1 2 3 4 5 6 7 8 9 10 11 12 13  0  1  2  3  4  5

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 más grande... 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.