Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да направите RAND() детерминистичен в SQL Server

RAND() функция в SQL Server връща псевдослучайна плаваща стойност от 0 до 1, изключителна.

Тази функция може да бъде детерминирана или недетерминистична, в зависимост от това как е извикана.

Детерминистичните функции винаги връщат един и същ резултат за даден набор от входни стойности и при едно и също състояние на базата данни. Недетерминистичните функции могат да върнат различен резултат със същия набор от входни стойности и дори състоянието на базата данни да остане същото.

RAND() функцията може да бъде извикана по два начина; със семе и без семе. Ако го наречете без семена, това е недетерминистично. Ако го наречете със семе, това е детерминистично.

С други думи, за определена начална стойност, връщаният резултат винаги е един и същ.

Но има проблем:понякога се извиква RAND() без семее детерминистичен. Обяснявам това по-долу.

Синтаксис

Първо, ето синтаксиса:

RAND ( [ seed ] )

Квадратните скоби означават, че аргументът seed е незадължителен.

Пример 1 – Без семена

Тук викам RAND() пет пъти без семе.

SELECT RAND() AS [No Seed]
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()
UNION ALL
SELECT RAND()

Резултат:

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

Всеки ред има различна стойност.

Пример 2 – Със семена

Тук изпълнявам същата заявка, освен че добавям едно и също начало към всяко извикване на функция.

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)

Резултат:

+-------------------+
| With Seed         |
|-------------------|
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
| 0.715436657367485 |
+-------------------+

В този случай всички редове имат една и съща стойност.

Пример 3 – Комбинирайте начално и без начално число в една и съща заявка (множество RAND() повиквания)

Трябва да внимавате, когато извиквате RAND() няколко пъти в една и съща връзка. Ако извикате RAND() с определена начална стойност, всички последващи извиквания на RAND() произвеждат резултати въз основа на зародения RAND() обадете се.

Така че можете по невнимание да си помислите, че изпълнявате RAND() недетерминистично, когато всъщност не сте.

Ето пример за демонстрация.

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];

Резултат:

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

Въпреки че резултантната стойност е различна в колоните, всяко повикване „без начално число“ всъщност се основава на извикването „with seed“ и следователно е детерминирано.

Ако разбъркам извикванията на функциите, ето какво получавам.

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];

Резултат:

+------------------+--------------------+-------------------+
| 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Какво прави тази заявка за създаване на разделен със запетая списък SQL Server?

  2. Вижте дали дадена таблица има ограничение по подразбиране в SQL Server, като използвате OBJECTPROPERTY()

  3. Поправка:„BACKUP LOG не може да се извърши, защото няма текущо архивиране на базата данни.“ в SQL Server/SQL Edge

  4. Възстановяване на основната база данни на SQL Server

  5. Какво да направите за типа на изчакване на ASYNC NETWORK IO?