sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man gör RAND() deterministisk i SQL Server

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

  1. Observer Overhead- och väntetypssymptom

  2. Hur kör man SQLite-fråga asynkront på bakgrundstråden?

  3. Okänd kolumn i "fältlista"-fel på MySQL Update-fråga

  4. Olika tidszonstyper på DateTime-objektet