Использование встроенной функции rand() в запросах чревато проблемой получения последовательности одинаковых чисел. Например
CREATE TABLE T1 (id int); GO INSERT INTO T1 SELECT 1 UNION SELECT 2 UNION SELECT 3; SELECT rand(), id FROM T1;
Выдает одинаковые значения
rand_value id ---------------------- ----------- 0,581556027773794 1 0,581556027773794 2 0,581556027773794 3 (3 row(s) affected)
Конечно, можно написать свою функцию - аналог rand(), используя один из алгоритмов генерации псевдослучайно последовательности. Но попробуем справиться встроенными средствами.
Если подавать на вход rand() в качестве параметра "seed" (инициализатора) псевдослучайные целые числа, то и на выходе мы получим псевдослучайную последовательность в диапазоне (0, 1). В качестве поставщика чисел для seed подойдет генератор GUID - функция newid(). Например так:
rand(abs(convert(int, convert(varbinary, newid()))))
Обернуть rand() в пользовательскую скалярную функцию нельзя согласно ограничениям MS SQL Server. Воспользуемся проекцией (view).
CREATE VIEW rand2 AS SELECT rand(abs(convert(int, convert(varbinary, newid())))) AS rand_value;
Использовать проекцию в запросах можно так:
SELECT rand2.rand_value, id FROM T1 CROSS JOIN rand2;
или так:
SELECT (SELECT rand_value FROM rand2) AS rand_value, id FROM T1;
Повторив тест, получаем
rand_value id ---------------------- ----------- 0,349013124792225 1 0,780734712117597 2 0,488939877887713 3 (3 row(s) affected
За рамками заметки остается вопрос длины псевдослучайной последовательности. Оставляю этот вопрос читателю.