RAND()
funktion i SQL Server returnerer en pseudo-tilfældig flydende værdi fra 0 til 1, eksklusiv.
Denne funktion kan være deterministisk eller ikke-deterministisk, afhængigt af hvordan den aktiveres.
Deterministiske funktioner returnerer altid det samme resultat for et givet sæt inputværdier og givet den samme tilstand af databasen. Ikke-deterministiske funktioner kan returnere et andet resultat med det samme sæt af inputværdier, og selvom databasetilstanden forbliver den samme.
RAND()
funktion kan kaldes på to måder; med et frø og uden et frø. Hvis du kalder det uden et frø, er det ikke-deterministisk. Hvis du kalder det med et frø, er det deterministisk.
Med andre ord, for en specificeret startværdi er det returnerede resultat altid det samme.
Men der er en gotcha:Kalder nogle gange RAND()
uden et frø er deterministisk. Jeg forklarer dette nedenfor.
Syntaks
Først her er syntaksen:
RAND ( [ seed ] )
De firkantede parenteser betyder, at startargumentet er valgfrit.
Eksempel 1 – Ingen frø
Her kalder jeg RAND()
fem gange uden 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 | +-------------------+
Hver række har en forskellig værdi.
Eksempel 2 – Med frø
Her kører jeg den samme forespørgsel, bortset fra at jeg tilføjer det samme frø til hvert funktionskald.
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 dette tilfælde har alle rækker den samme værdi.
Eksempel 3 – Kombiner Seed og No Seed i samme forespørgsel (Flere RAND()-kald)
Du skal være forsigtig, når du kalder RAND()
flere gange i samme forbindelse. Hvis du kalder RAND()
med en specificeret startværdi, alle efterfølgende kald af RAND()
producere resultater baseret på den seedede RAND()
opkald.
Så du kan uforvarende tro, at du udfører RAND()
ikke-deterministisk, når du faktisk ikke er det.
Her er et eksempel til at demonstrere.
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 | +-------------------+------------------+--------------------+
Selvom den resulterende værdi er forskellig på tværs af kolonnerne, var hvert "no seed"-kald faktisk baseret på "with seed"-kaldet og derfor deterministisk.
Hvis jeg blander funktionsopkaldene rundt, får jeg det her.
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 | +------------------+--------------------+-------------------+