La séquence pseudo-aléatoire en requêtes Transact SQL

La fonction rand() de Transact SQL produit la séquence de nombres identiques dans les requêtes. Par exemple :

SELECT rand() AS rand_value, id 
   FROM 
      (SELECT 1 AS id
          UNION
       SELECT 2 AS id
          UNION
       SELECT 3 AS id
      ) AS T1;

Ce code nous affiche le résultat suivant :

rand_value             id
---------------------- -----------
0,581556027773794      1
0,581556027773794      2
0,581556027773794      3
 
(3 row(s) affected)

Certainement, nous pouvons développer la fonction pareil propriétaire en prenant l'une des algorithmes de génération des séquences pseudo-aléatoires. Mais on tente de ne pas élargir l'ensemble des fonctions standards d'abord.

En passant les nombres entiers comme le paramètre d'entrée (seed) de la fonction rand() nous aurons la séquence pseudo-aléatoire dans l'intervalle (0, 1) à la sortie. Mais d'où récupérer ces nombres entiers ? Heureusement, les valeurs de type GUID dont la fonction newid() génère, ils sont convenables après avoir converti. Par exemple :

rand(abs(convert(int, convert(varbinary, newid()))))

Puisque il n'est pas possible d'utiliser la fonction standard rand() dans la fonction d'utilisateur en MS SQL Server on créera la vue pour encapsuler notre générateur.

CREATE VIEW rand2 AS 
  SELECT rand(abs(convert(int, convert(varbinary, newid())))) AS rand_value;

Maintenant nous sommes capables utiliser cette vue dans nos requêtes :

SELECT rand2.rand_value, id FROM T1 CROSS JOIN rand2

ou

SELECT (SELECT rand_value FROM rand2) AS rand_value, id FROM T1

On reprend notre première test et voila !

rand_value             id
---------------------- -----------
0,349013124792225      1
0,780734712117597      2
0,488939877887713      3
 
(3 row(s) affected

Néanmoins, la question concernant de la longueur de cette séquence pseudo-aléatoire reste inexplorée. Je vous laisse réfléchir au dessus.