sql >> Databáze >  >> RDS >> Sqlserver

Jak udělat RAND() deterministický v SQL Server

RAND() funkce na serveru SQL Server vrací pseudonáhodnou plovoucí hodnotu od 0 do 1, s výjimkou.

Tato funkce může být deterministická nebo nedeterministická, v závislosti na tom, jak je vyvolána.

Deterministické funkce vždy vrátí stejný výsledek pro danou sadu vstupních hodnot a daný stejný stav databáze. Nedeterministické funkce mohou vrátit jiný výsledek se stejnou sadou vstupních hodnot, i když stav databáze zůstane stejný.

RAND() funkci lze volat dvěma způsoby; se semenem i bez semene. Pokud to nazýváte bez semene, je to nedeterministické. Pokud to nazýváte semenem, je to deterministické.

Jinými slovy, pro zadanou počáteční hodnotu je vrácený výsledek vždy stejný.

Ale je tu problém:Někdy se volá RAND() bez semene je deterministický. Vysvětluji to níže.

Syntaxe

Nejprve je zde syntaxe:

RAND ( [ seed ] )

Hranaté závorky znamenají, že argument zdroje je volitelný.

Příklad 1 – Bez semene

Zde volám RAND() pětkrát bez semene.

SELECT RAND() AS [No Seed]
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()

Výsledek:

+-------------------+
| No Seed           |
|-------------------|
| 0.2054995913191   |
| 0.821844434880088 |
| 0.4204955495022   |
| 0.286702661673299 |
| 0.394385747185196 |
+-------------------+

Každý řádek má jinou hodnotu.

Příklad 2 – Se semeny

Zde spustím stejný dotaz, kromě toho, že ke každému volání funkce přidám stejné semeno.

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)

Výsledek:

+-------------------+
| With Seed         |
|-------------------|
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
+-------------------+

V tomto případě mají všechny řádky stejnou hodnotu.

Příklad 3 – Kombinace počáteční a žádné počáteční hodnoty ve stejném dotazu (vícenásobná volání RAND())

Při volání RAND() musíte být opatrní vícekrát ve stejném spojení. Pokud zavoláte RAND() se zadanou počáteční hodnotou, všechna následující volání RAND() vytvářet výsledky založené na nasazeném RAND() volání.

Mohli byste si tedy neúmyslně myslet, že provádíte RAND() nedeterministicky, i když ve skutečnosti nejste.

Zde je příklad k demonstraci.

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];

Výsledek:

+-------------------+------------------+--------------------+
| With Seed         | No Seed          | No Seed            |
|-------------------+------------------+--------------------|
| 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
| 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
| 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
+-------------------+------------------+--------------------+

I když se výsledná hodnota v jednotlivých sloupcích liší, každé volání „bez semena“ bylo ve skutečnosti založeno na volání „se semenem“, a proto bylo deterministické.

Když zamíchám volání funkcí, dostanu toto.

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];

Výsledek:

+------------------+--------------------+-------------------+
| 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. Výkon SQL UNION vs. OR

  2. Vytvoření vlastní bitové kopie SQL Server Docker nad oficiální bitovou kopií

  3. Jak najít závislosti uvnitř balíčku Oracle?

  4. Nastavení fyzického pohotovostního režimu Active Data Guard v architektuře RAC One Node – část 2