De RAND()
functie in SQL Server retourneert een pseudo-willekeurige float-waarde van 0 tot en met 1, exclusief.
Deze functie kan deterministisch of niet-deterministisch zijn, afhankelijk van hoe deze wordt aangeroepen.
Deterministische functies retourneren altijd hetzelfde resultaat voor een bepaalde set invoerwaarden en met dezelfde status van de database. Niet-deterministische functies kunnen een ander resultaat opleveren met dezelfde set invoerwaarden en zelfs als de databasestatus hetzelfde blijft.
De RAND()
functie kan op twee manieren worden aangeroepen; met een zaad en zonder een zaad. Als je het zonder zaad noemt, is het niet-deterministisch. Als je het met een zaadje noemt, is het deterministisch.
Met andere woorden, voor een gespecificeerde seed-waarde is het geretourneerde resultaat altijd hetzelfde.
Maar er is een probleem:soms roept u RAND()
zonder een zaadje is deterministisch. Ik leg dit hieronder uit.
Syntaxis
Ten eerste, hier is de syntaxis:
RAND ( [ seed ] )
De vierkante haken betekenen dat het seed-argument optioneel is.
Voorbeeld 1 – Geen zaad
Hier noem ik RAND()
vijf keer zonder zaadje.
SELECT RAND() AS [No Seed] UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND() UNION ALL SELECT RAND()
Resultaat:
+-------------------+ | No Seed | |-------------------| | 0.2054995913191 | | 0.821844434880088 | | 0.4204955495022 | | 0.286702661673299 | | 0.394385747185196 | +-------------------+
Elke rij heeft een andere waarde.
Voorbeeld 2 – Met Zaad
Hier voer ik dezelfde query uit, behalve dat ik hetzelfde zaad aan elke functieaanroep toevoeg.
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)
Resultaat:
+-------------------+ | With Seed | |-------------------| | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | | 0.715436657367485 | +-------------------+
In dit geval hebben alle rijen dezelfde waarde.
Voorbeeld 3 – Combineer Seed en No Seed in dezelfde zoekopdracht (meerdere RAND()-aanroepen)
Je moet voorzichtig zijn bij het aanroepen van RAND()
meerdere keren in dezelfde verbinding. Als u RAND()
. aanroept met een gespecificeerde seed-waarde, alle volgende aanroepen van RAND()
resultaten produceren op basis van de geplaatste RAND()
telefoongesprek.
U zou dus per ongeluk kunnen denken dat u RAND()
. uitvoert niet-deterministisch, terwijl u dat in feite niet bent.
Hier is een voorbeeld om te demonstreren.
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];
Resultaat:
+-------------------+------------------+--------------------+ | With Seed | No Seed | No Seed | |-------------------+------------------+--------------------| | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 | +-------------------+------------------+--------------------+
Hoewel de resulterende waarde in de kolommen verschilt, was elke "no seed" -aanroep eigenlijk gebaseerd op de "with seed" -aanroep, en daarom deterministisch.
Als ik de functie-aanroepen door elkaar schud, krijg ik het volgende.
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];
Resultaat:
+------------------+--------------------+-------------------+ | No Seed | No Seed | With Seed | |------------------+--------------------+-------------------| | 0.28769876521071 | 0.100505471175005 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 | +------------------+--------------------+-------------------+