Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como tornar RAND() determinístico no SQL Server


O RAND() A função no SQL Server retorna um valor flutuante pseudoaleatório de 0 a 1, exclusivo.

Essa função pode ser determinística ou não determinística, dependendo de como é invocada.



As funções determinísticas sempre retornam o mesmo resultado para um determinado conjunto de valores de entrada e para o mesmo estado do banco de dados. Funções não determinísticas podem retornar um resultado diferente com o mesmo conjunto de valores de entrada e mesmo que o estado do banco de dados permaneça o mesmo.

O RAND() função pode ser chamada de duas maneiras; com semente e sem semente. Se você chamá-lo sem uma semente, é não determinístico. Se você chamá-lo com uma semente, é determinístico.

Em outras palavras, para um valor de semente especificado, o resultado retornado é sempre o mesmo.

Mas há uma pegadinha:às vezes chamando RAND() sem uma semente é determinista. Eu explico isso abaixo.

Sintaxe


Primeiro, aqui está a sintaxe:
RAND ( [ seed ] )

Os colchetes significam que o argumento seed é opcional.

Exemplo 1 – Sem Semente


Aqui eu chamo RAND() cinco vezes sem uma semente.
SELECT RAND() AS [No Seed]
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()

Resultado:
+-------------------+
| No Seed           |
|-------------------|
| 0.2054995913191   |
| 0.821844434880088 |
| 0.4204955495022   |
| 0.286702661673299 |
| 0.394385747185196 |
+-------------------+

Cada linha tem um valor diferente.

Exemplo 2 – Com Semente


Aqui eu executo a mesma consulta, exceto que adiciono a mesma semente a cada chamada de função.
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)

Resultado:
+-------------------+
| With Seed         |
|-------------------|
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
+-------------------+

Nesse caso, todas as linhas têm o mesmo valor.

Exemplo 3 - Combinar Semente e Sem Semente na Mesma Consulta (Várias Chamadas RAND())


Você precisa ter cuidado ao chamar RAND() várias vezes na mesma conexão. Se você chamar RAND() com um valor de semente especificado, todas as chamadas subsequentes de RAND() produzir resultados com base no RAND() semeado ligar.

Então você pode pensar inadvertidamente que está executando RAND() não determinística quando na verdade você não é.

Aqui está um exemplo para demonstrar.
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];

Resultado:
+-------------------+------------------+--------------------+
| With Seed         | No Seed          | No Seed            |
|-------------------+------------------+--------------------|
| 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
| 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
| 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
+-------------------+------------------+--------------------+

Mesmo que o valor resultante seja diferente nas colunas, cada chamada “sem semente” foi na verdade baseada na chamada “com semente” e, portanto, determinística.

Se eu embaralhar as chamadas de função, aqui está o que eu recebo.
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];

Resultado:
+------------------+--------------------+-------------------+
| No Seed          | No Seed            | With Seed         |
|------------------+--------------------+-------------------|
| 0.28769876521071 | 0.100505471175005  | 0.715436657367485 |
| 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 |
| 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 |
+------------------+--------------------+-------------------+