329 votes

Comment générer un nombre aléatoire pour chaque ligne dans un TSQL Select?

<p>J’ai besoin d’un nombre aléatoire différent pour chaque ligne dans ma table. Le code suivant apparemment évident utilise la même valeur aléatoire pour chaque ligne.<pre><code></code></pre><p>Je voudrais obtenir un INT ou un flotteur sur cela. Le reste de l’histoire est que je vais utiliser le nombre aléatoire pour créer un décalage de date aléatoire à partir d’une date de savoir, par exemple offset de 1 à 14 jours entre une date de début.</p><p>Il s’agit pour Microsoft SQL Server 2000.</p></p>

519voto

SQLMenace Points 68670

Prendre un regard sur SQL Server - configurer en fonction de nombres aléatoires , qui a une très explication détaillée.

Pour résumer, le code suivant génère un nombre aléatoire entre 0 et 13 inclusive avec un normalisée de distribution:

ABS(CHECKSUM(NewId())) % 14

Pour modifier votre portée, il suffit de changer le numéro à la fin de l'expression. Soyez très prudent si vous avez besoin d'une gamme 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 maths noix dans la salle: il y a un très léger biais dans le présent code. CHECKSUM() résultats dans les chiffres qui sont normalisées dans toute la gamme de sql Int type de données, ou tout au moins à proximité de sorte que mon (de l'éditeur) les tests peuvent montrer. Cependant, il y aura un certain biais lorsque la somme de contrôle() génère un nombre au très haut de gamme. Chaque fois que vous obtenez un nombre entre le maximum possible entier et la dernière multiple exact de la taille de votre gamme désirée (14 dans ce cas) avant que l'entier maximal, ces résultats sont favorisées par rapport à la partie restante de votre gamme qui ne peuvent être fabriqués à partir de cette dernière multiple de 14.

Par exemple, imaginez que l'ensemble de la gamme du type Int est de seulement 19. 19 est le plus grand entier que vous pouvez tenir. Lorsque la somme de contrôle (en) résultats dans les 14-19 ans, ceux-ci correspondent aux résultats de 0 à 5 ans. Ces chiffres seraient fortement favorisée par rapport à 6-13, en raison de la somme de contrôle() est deux fois plus susceptibles de les générer. Il est plus facile de le démontrer visuellement. Ci-dessous l'intégralité du possible l'ensemble des résultats de notre imaginaire entier portée:

Somme De Contrôle Entier: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Plage De Suite: 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 des chiffres que les autres: des biais. Heureusement, la portée réelle du type Int est beaucoup plus grande... tant et si bien que, dans la plupart des cas, le biais est presque indétectable. Cependant, il est quelque chose d'être conscient de si vous vous trouvez jamais de le faire pour de graves code de sécurité.

95voto

Jeremy Smyth Points 11001
<p>Lorsqu’elle est appelée plusieurs fois en un seul lot, rand() retourne le même numéro.<p>Je suggère d’utiliser convert(varbinary,newid()) comme argument de semences :</p><pre><code></code></pre><p>NEWID() est garanti pour retourner une valeur différente chaque fois qu’on l’appelle, même au sein d’un même lot, donc utiliser comme une graine invitera rand() pour donner une valeur différente chaque fois.</p><p>Édité pour obtenir un nombre entier aléatoire de 1 à 14.</p></p>

73voto

Aaron Hoffman Points 2696
RAND(CHECKSUM(NEWID()))

Le ci-dessus va générer une (pseudo-) nombre aléatoire entre 0 et 1, exclusif. Si l'on utilise un select, parce que la semence de changement de la valeur pour chaque ligne, il va générer un nouveau nombre aléatoire pour chaque ligne (il n'est pas garanti pour générer un numéro unique par ligne).

Exemple lorsqu'il est combiné avec une limite supérieure de 10 (produit des nombres de 1 à 10):

CAST(RAND(CHECKSUM(NEWID())) * 10 as INT) + 1

RAND(): http://msdn.microsoft.com/en-us/library/ms177610.aspx

Somme de contrôle(): http://msdn.microsoft.com/en-us/library/ms189788.aspx

13voto

MicSim Points 12980
<p>La fonction Rand() génère le nombre aléatoire même, si utilisé dans une requête SELECT de la table. Il en va de même si vous utilisez une graine à la fonction Rand. Une autre façon de le faire, utilise ceci :<pre><code></code></pre><p>A obtenu l’information d' <a href="http://www.sql-server-helper.com/tips/generate-random-numbers.aspx" rel="nofollow">ici</a>, qui l’explique très bien le problème.</p></p>

4voto

northpole Points 5793
<p>essayez d’utiliser une valeur initiale dans le RAND(seedInt). Rand() s’exécutera seulement une fois après une déclaration qui explique pourquoi vous voyez le même nombre à chaque fois.</p>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X