Псевдослучайная последовательность в SQL Server
Использование встроенной функции 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
За рамками заметки остается вопрос длины псевдослучайной последовательности. Оставляю этот вопрос читателю.
blog comments powered by Disqus