RAND()
funkcja w SQL Server zwraca pseudolosową wartość zmiennoprzecinkową od 0 do 1, wyłączne.
Ta funkcja może być deterministyczna lub niedeterministyczna, w zależności od sposobu jej wywołania.
Funkcje deterministyczne zawsze zwracają ten sam wynik dla danego zestawu wartości wejściowych i przy takim samym stanie bazy danych. Funkcje niedeterministyczne mogą zwracać inny wynik z tym samym zestawem wartości wejściowych, a nawet jeśli stan bazy danych pozostaje taki sam.
RAND()
funkcję można wywołać na dwa sposoby; z nasieniem i bez nasienia. Jeśli nazwiesz to bez nasion, jest to niedeterministyczne. Jeśli nazwiesz to ziarnem, jest to deterministyczne.
Innymi słowy, dla określonej wartości początkowej zwracany wynik jest zawsze taki sam.
Ale jest pewien problem:czasami wywoływanie RAND()
bez nasion jest deterministyczny. Wyjaśniam to poniżej.
Składnia
Po pierwsze, oto składnia:
RAND ( [ seed ] )
Nawiasy kwadratowe oznaczają, że argument seed jest opcjonalny.
Przykład 1 – Brak nasion
Tutaj wywołuję RAND()
pięć razy bez nasion.
SELECT RAND() AS [No Seed] UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND()
Wynik:
+-------------------+ | No Seed | |-------------------| | 0.2054995913191 | | 0.821844434880088 | | 0.4204955495022 | | 0.286702661673299 | | 0.394385747185196 | +-------------------+
Każdy wiersz ma inną wartość.
Przykład 2 – z nasionami
Tutaj uruchamiam to samo zapytanie, z wyjątkiem tego, że do każdego wywołania funkcji dodaję to samo ziarno.
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)
Wynik:
+-------------------+ | With Seed | |-------------------| | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | +-------------------+
W takim przypadku wszystkie wiersze mają tę samą wartość.
Przykład 3 – Łączenie nasion i brak nasion w tym samym zapytaniu (wielokrotne wywołania RAND())
Musisz być ostrożny podczas wywoływania RAND()
wielokrotnie w tym samym połączeniu. Jeśli wywołasz RAND()
z określoną wartością inicjatora, wszystkie kolejne wywołania RAND()
generować wyniki na podstawie zaszczepionego RAND()
połączenie.
Możesz więc nieumyślnie pomyśleć, że wykonujesz RAND()
niedeterministycznie, podczas gdy w rzeczywistości tak nie jest.
Oto przykład do zademonstrowania.
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];
Wynik:
+-------------------+------------------+--------------------+ | With Seed | No Seed | No Seed | |-------------------+------------------+--------------------| | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | +-------------------+------------------+--------------------+
Mimo że wynikowa wartość różni się w poszczególnych kolumnach, każde wywołanie „bez nasion” było w rzeczywistości oparte na wywołaniu „z nasionami”, a zatem było deterministyczne.
Oto, co otrzymam, jeśli przetasuję wywołania funkcji.
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];
Wynik:
+------------------+--------------------+-------------------+ | No Seed | No Seed | With Seed | |------------------+--------------------+-------------------| | 0.28769876521071 | 0.100505471175005 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | +------------------+--------------------+-------------------+