Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment générer un nombre aléatoire pour chaque ligne dans une sélection T-SQL ?

Jetez un œil à SQL Server - Définir des nombres aléatoires basés sur des nombres aléatoires qui ont une explication très détaillée.

Pour résumer, le code suivant génère un nombre aléatoire compris entre 0 et 13 inclus avec une distribution uniforme :

ABS(CHECKSUM(NewId())) % 14
 

Pour modifier votre plage, modifiez simplement le nombre à la fin de l'expression. Soyez très prudent si vous avez besoin d'une plage qui comprend à la fois des nombres positifs et négatifs. Si vous le faites mal, il est possible de compter deux fois le nombre 0.

Un petit avertissement pour les fous de maths dans la salle :il y a un très léger biais dans ce code. CHECKSUM() donne des nombres uniformes sur toute la plage du type de données sql Int, ou au moins aussi proches que mes tests (l'éditeur) peuvent le montrer. Cependant, il y aura un certain biais lorsque CHECKSUM() produira un nombre tout en haut de cette plage. Chaque fois que vous obtenez un nombre entre l'entier maximum possible et le dernier multiple exact de la taille de votre plage souhaitée (14 dans ce cas) avant cet entier maximum, ces résultats sont favorisés par rapport à la partie restante de votre plage qui ne peut pas être produite à partir de ce dernier multiple de 14.

Par exemple, imaginez que la plage entière du type Int ne soit que 19. 19 est le plus grand nombre entier possible que vous puissiez contenir. Lorsque CHECKSUM() donne 14-19, ceux-ci correspondent aux résultats 0-5. Ces chiffres seraient fortement préféré à 6-13, car CHECKSUM() est deux fois plus susceptible de les générer. Il est plus facile de le démontrer visuellement. Vous trouverez ci-dessous l'ensemble des résultats possibles pour notre plage d'entiers imaginaires :

Checksum Entier :0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19Résultat de plage :0 1 2 3 4 5 6 7 8 9 10 11 12 13 0 1 2 3 4 5 

Vous pouvez voir ici qu'il y a plus de chances de produire certains nombres que d'autres :le biais. Heureusement, la plage réelle du type Int est beaucoup plus grand ... à tel point que dans la plupart des cas, le biais est presque indétectable. Cependant, c'est quelque chose dont il faut être conscient si jamais vous vous retrouvez à faire cela pour un code de sécurité sérieux.