Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak zrobić deterministyczny RAND() w SQL Server

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 |
+------------------+--------------------+-------------------+

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. T-SQL:Jak używać parametrów w dynamicznym SQL?

  2. Użyj DB_ID(), aby zwrócić identyfikator bazy danych w SQL Server

  3. RODBC odbcDriverConnect() Błąd połączenia

  4. jak rozdzielić ciąg na różne kolumny?

  5. Dzielenie wartości rozdzielonych przecinkami w kolumnach na wiele wierszy w Sql Server