RAND()
funktion i SQL Server returnerar ett pseudo-slumpmässigt flytande värde från 0 till 1, exklusivt.
Denna funktion kan vara deterministisk eller icke-deterministisk, beroende på hur den anropas.
Deterministiska funktioner returnerar alltid samma resultat för en given uppsättning ingångsvärden och givet samma tillstånd i databasen. Icketerministiska funktioner kan returnera ett annat resultat med samma uppsättning indata och även om databastillståndet förblir detsamma.
RAND()
funktion kan anropas på två sätt; med ett frö och utan ett frö. Om du kallar det utan ett frö är det icke-deterministiskt. Om du kallar det med ett frö är det deterministiskt.
Med andra ord, för ett specificerat startvärde är resultatet som returneras alltid detsamma.
Men det finns något:Kallar ibland RAND()
utan ett frö är deterministisk. Jag förklarar detta nedan.
Syntax
Först, här är syntaxen:
RAND ( [ seed ] )
Hakparenteserna betyder att fröargumentet är valfritt.
Exempel 1 – Inget frö
Här anropar jag RAND()
fem gånger utan frö.
SELECT RAND() AS [No Seed] UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND()
Resultat:
+-------------------+ | No Seed | |-------------------| | 0.2054995913191 | | 0.821844434880088 | | 0.4204955495022 | | 0.286702661673299 | | 0.394385747185196 | +-------------------+
Varje rad har olika värde.
Exempel 2 – Med utsäde
Här kör jag samma fråga, förutom att jag lägger till samma frö till varje funktionsanrop.
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)
Resultat:
+-------------------+ | With Seed | |-------------------| | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | +-------------------+
I det här fallet har alla rader samma värde.
Exempel 3 – Kombinera Seed och No Seed i samma fråga (flera RAND()-anrop)
Du måste vara försiktig när du anropar RAND()
flera gånger i samma anslutning. Om du anropar RAND()
med ett specificerat startvärde, alla efterföljande anrop av RAND()
producera resultat baserat på den seedade RAND()
ringa upp.
Så du kan av misstag tro att du kör RAND()
icke-deterministiskt när du faktiskt inte är det.
Här är ett exempel att visa.
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];
Resultat:
+-------------------+------------------+--------------------+ | With Seed | No Seed | No Seed | |-------------------+------------------+--------------------| | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | +-------------------+------------------+--------------------+
Även om det resulterande värdet är olika mellan kolumnerna, var varje "no seed"-anrop faktiskt baserat på "with seed"-anropet och därför deterministiskt.
Om jag blandar runt funktionsanropen får jag det här.
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];
Resultat:
+------------------+--------------------+-------------------+ | No Seed | No Seed | With Seed | |------------------+--------------------+-------------------| | 0.28769876521071 | 0.100505471175005 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | +------------------+--------------------+-------------------+