[sql-server] TSQL Select의 각 행에 대해 난수를 어떻게 생성합니까?

내 테이블의 각 행마다 다른 임의의 숫자가 필요합니다. 다음의 명백한 코드는 각 행에 대해 동일한 임의의 값을 사용합니다.

SELECT table_name, RAND() magic_number
FROM information_schema.tables 

이 중 INT 또는 FLOAT를 얻고 싶습니다. 이야기의 나머지 부분은이 난수를 사용하여 알려진 날짜에서 임의의 날짜 오프셋을 생성합니다 (예 : 시작 날짜에서 1-14 일 오프셋).

Microsoft SQL Server 2000 용입니다.



답변

SQL Server-Set based random numbers 를 살펴보십시오 . 자세한 설명이 나와 있습니다.

요약하면, 다음 코드는 균일 분포로 0에서 13 사이의 난수를 생성합니다.

ABS(CHECKSUM(NewId())) % 14

범위를 변경하려면 식 끝에 숫자를 변경하십시오. 양수와 음수를 모두 포함하는 범위가 필요한 경우 각별히주의하십시오. 잘못하면 숫자 0을 두 번 계산할 수 있습니다.

방의 수학 너트에 대한 작은 경고 :이 코드에는 약간의 편견이 있습니다. CHECKSUM()sql Int 데이터 유형의 전체 범위에서 균일하거나 최소한 (편집자) 테스트가 표시 할 수있는 정도의 숫자가됩니다. 그러나 CHECKSUM ()이 해당 범위의 맨 끝에 숫자를 생성 할 때 약간의 편차가 있습니다. 가능한 최대 정수와 원하는 최대 크기 (이 경우 14)의 크기의 마지막 정확한 배수 사이의 숫자를 얻을 때마다 그 결과는 범위의 나머지 부분보다 선호됩니다. 마지막 배수는 14의 배수입니다.

예를 들어, Int 유형의 전체 범위가 19에 불과하다고 가정하십시오. 19는 보유 할 수있는 가장 큰 정수입니다. CHECKSUM ()의 결과가 14-19 인 경우 결과 0-5에 해당합니다. CHECKSUM ()이 생성 할 가능성이 두 배이기 때문에이 숫자는 6-13보다 많이 선호됩니다. 이것을 시각적으로 설명하는 것이 더 쉽습니다. 다음은 가상 정수 범위에 대한 가능한 전체 결과 집합입니다.

체크섬 정수 : 12 34 5678 9 10 11 12 1314 15 16 17 18 19
범위 결과 : 12 34 5678 9 10 11 12 1103 34 5

여기에서 다른 것보다 더 많은 숫자를 생성 할 수있는 기회가 더 많다는 것을 알 수 있습니다 : 편향. 고맙게도 Int 유형의 실제 범위는 훨씬 큽니다. 그래서 대부분의 경우 바이어스를 거의 감지 할 수 없습니다. 그러나 심각한 보안 코드를 위해이 작업을 수행하는 경우 알고 있어야합니다.


답변

단일 배치에서 여러 번 호출되면 rand ()는 동일한 숫자를 반환합니다.

시드 인수로 convert ( varbinary, newid())를 사용하는 것이 좋습니다 .

SELECT table_name, 1.0 + floor(14 * RAND(convert(varbinary, newid()))) magic_number
FROM information_schema.tables

newid() 같은 배치 내에서도 호출 될 때마다 다른 값을 반환하도록 보장되므로 시드로 사용하면 rand ()가 매번 다른 값을 지정하도록 프롬프트합니다.

1에서 14까지 임의의 정수를 얻도록 편집되었습니다.


답변

RAND(CHECKSUM(NEWID()))

위의 0과 1 사이의 (의사) 난수를 제외하고 생성합니다. 선택에 사용될 경우 각 행의 시드 값이 변경되므로 각 행에 대해 새로운 난수를 생성합니다 (단, 행당 고유 한 숫자를 생성 할 수는 없습니다).

상한을 10으로 조합 한 예 (숫자 1 ~ 10 생성) :

CAST(RAND(CHECKSUM(NEWID())) * 10 as INT) + 1

Transact-SQL 설명서 :

  1. CAST(): https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
  2. RAND(): http://msdn.microsoft.com/en-us/library/ms177610.aspx
  3. CHECKSUM(): http://msdn.microsoft.com/en-us/library/ms189788.aspx
  4. NEWID(): https://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sql

답변

1000에서 9999 사이의 난수 생성 :

FLOOR(RAND(CHECKSUM(NEWID()))*(9999-1000+1)+1000)

“+1”-상한값 포함 (이전 예의 경우 9999)


답변

이전 질문에 대답했지만이 답변은 이전에 제공되지 않았으므로 검색 엔진을 통해이 결과를 찾는 사람에게 유용 할 것입니다.

SQL Server 2008 CRYPT_GEN_RANDOM(8)에는 CryptoAPI를 사용하여 암호화 적으로 강력한 난수를 생성하는 새로운 기능이 도입되었으며 로 반환됩니다 VARBINARY(8000). 설명서 페이지는 다음과 같습니다. https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sql

임의의 숫자를 얻으려면 간단히 함수를 호출하여 필요한 유형으로 캐스팅하면됩니다.

select CAST(CRYPT_GEN_RANDOM(8) AS bigint)

또는 float-1과 +1 사이 를 얻으려면 다음과 같이 할 수 있습니다.

select CAST(CRYPT_GEN_RANDOM(8) AS bigint) % 1000000000 / 1000000000.0


답변

Rand () 함수는 테이블 SELECT 쿼리에 사용되는 경우 동일한 난수를 생성합니다. Rand 함수에 시드를 사용하는 경우에도 동일하게 적용됩니다. 다른 방법은 다음을 사용하는 것입니다.

SELECT ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RandomNumber]

여기 에서 정보를 얻었습니다 . 문제를 잘 설명합니다.


답변

RAND 함수에 시드로 전달할 수있는 각 행에 정수 값이 있습니까?

1과 14 사이의 정수를 얻으려면 이것이 효과가 있다고 생각합니다.

FLOOR( RAND(<yourseed>) * 14) + 1