RAND()
функция в SQL Server връща псевдослучайна плаваща стойност от 0 до 1, изключителна.
Тази функция може да бъде детерминирана или недетерминистична, в зависимост от това как е извикана.
Детерминистичните функции винаги връщат един и същ резултат за даден набор от входни стойности и при едно и също състояние на базата данни. Недетерминистичните функции могат да върнат различен резултат със същия набор от входни стойности и дори състоянието на базата данни да остане същото.
RAND()
функцията може да бъде извикана по два начина; със семе и без семе. Ако го наречете без семена, това е недетерминистично. Ако го наречете със семе, това е детерминистично.
С други думи, за определена начална стойност, връщаният резултат винаги е един и същ.
Но има проблем:понякога се извиква RAND()
без семее детерминистичен. Обяснявам това по-долу.
Синтаксис
Първо, ето синтаксиса:
RAND ( [ seed ] )
Квадратните скоби означават, че аргументът seed е незадължителен.
Пример 1 – Без семена
Тук викам RAND()
пет пъти без семе.
SELECT RAND() AS [No Seed] UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND()
Резултат:
+-------------------+ | No Seed | |-------------------| | 0.2054995913191 | | 0.821844434880088 | | 0.4204955495022 | | 0.286702661673299 | | 0.394385747185196 | +-------------------+
Всеки ред има различна стойност.
Пример 2 – Със семена
Тук изпълнявам същата заявка, освен че добавям едно и също начало към всяко извикване на функция.
SELECT RAND(100) AS [With Seed] UNION ALL SELECT RAND(100) UNION ALL SELECT RAND(100) UNION ALL SELECT RAND(100) UNION ALL SELECT RAND(100)
Резултат:
+-------------------+ | With Seed | |-------------------| | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | +-------------------+
В този случай всички редове имат една и съща стойност.
Пример 3 – Комбинирайте начално и без начално число в една и съща заявка (множество RAND() повиквания)
Трябва да внимавате, когато извиквате RAND()
няколко пъти в една и съща връзка. Ако извикате RAND()
с определена начална стойност, всички последващи извиквания на RAND()
произвеждат резултати въз основа на зародения RAND()
обадете се.
Така че можете по невнимание да си помислите, че изпълнявате RAND()
недетерминистично, когато всъщност не сте.
Ето пример за демонстрация.
SELECT RAND(100) AS [With Seed], RAND() AS [No Seed], RAND() AS [No Seed] UNION ALL SELECT RAND(100) AS [With Seed], RAND() AS [No Seed], RAND() AS [No Seed] UNION ALL SELECT RAND(100) AS [With Seed], RAND() AS [No Seed], RAND() AS [No Seed];
Резултат:
+-------------------+------------------+--------------------+ | With Seed | No Seed | No Seed | |-------------------+------------------+--------------------| | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | +-------------------+------------------+--------------------+
Въпреки че резултантната стойност е различна в колоните, всяко повикване „без начално число“ всъщност се основава на извикването „with seed“ и следователно е детерминирано.
Ако разбъркам извикванията на функциите, ето какво получавам.
SELECT RAND() AS [No Seed], RAND() AS [No Seed], RAND(100) AS [With Seed] UNION ALL SELECT RAND() AS [No Seed], RAND() AS [No Seed], RAND(100) AS [With Seed] UNION ALL SELECT RAND() AS [No Seed], RAND() AS [No Seed], RAND(100) AS [With Seed];
Резултат:
+------------------+--------------------+-------------------+ | No Seed | No Seed | With Seed | |------------------+--------------------+-------------------| | 0.28769876521071 | 0.100505471175005 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | +------------------+--------------------+-------------------+