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