T-SQL 선택에서 각 행에 대해 난수를 생성하려면 어떻게 해야 합니까?
테이블의 각 행마다 다른 난수가 필요합니다.다음 명백한 코드는 각 행에 동일한 랜덤 값을 사용합니다.
SELECT table_name, RAND() magic_number
FROM information_schema.tables
INT나 Float를 받고 싶습니다.나머지 내용은 이 랜덤 숫자를 사용하여 알려진 날짜로부터 랜덤 날짜 오프셋을 만듭니다(예: 시작 날짜로부터 1-14일 오프셋).
이것은 Microsoft SQL Server 2000용입니다.
SQL Server - 매우 자세한 설명이 있는 난수 설정(Set based random number)을 참조하십시오.
요약하면, 다음 코드는 균일한 분포를 가진 0에서 13 사이의 난수를 생성합니다.
ABS(CHECKSUM(NewId())) % 14
범위를 변경하려면 식 끝의 숫자를 변경하기만 하면 됩니다.양수와 음수를 모두 포함하는 범위가 필요한 경우 각별히 주의하십시오.잘못하면 숫자 0을 이중으로 셀 수 있습니다.
방에 있는 수학 견과류에 대한 작은 경고: 이 코드에는 매우 작은 편향이 있습니다. CHECKSUM()
) 에서 표시할수 에서 일치하는 번호가 됩니다.sql Int는 최소한 이 테스트에 가깝습니다. CHECKSUM()이 그 의 편견이 합니다.가능한 최대 정수와 원하는 범위의 크기(이 경우 14)의 마지막 배수 사이의 값이 최대 정수보다 앞에 있을 때마다 이 결과는 범위의 마지막 배수인 14보다 우선됩니다.
예를 들어 Int 유형의 전체 범위가 19에 불과하다고 가정합니다. 19가 유지할 수 있는 최대 정수입니다.CHECKSUM() 결과 14~19일 경우 결과 0-5에 해당합니다.CHECKSUM()이 생성될 가능성이 2배 높기 때문에 이 숫자는 6-13보다 훨씬 선호됩니다.이를 시각적으로 설명하는 것이 더 쉽습니다.다음은 가상 정수 범위에 대해 가능한 전체 결과 집합입니다.
체크섬 정수: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19범위 결과: 0 1 2 3 4 5 6 7 8 9 10 11 13 0 1 2 3 4 5
여기서 볼 수 있듯이 다른 수치보다 더 많은 수의 수치를 산출할 수 있습니다. 편견입니다.다행히 Int 타입의 실제 범위는 훨씬 넓어...대부분의 경우 편견이 거의 감지되지 않을 정도로요단, 심각한 보안 코드를 위해 이 작업을 수행하는 경우 주의해야 할 사항입니다.
단일 배치로 여러 번 호출하면 rand()는 동일한 번호를 반환합니다.
convert)을 사용하는 것이 varbinary
,newid()
로서 seed를 사용합니다.
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 문서:
CAST()
: https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sqlRAND()
: http://msdn.microsoft.com/en-us/library/ms177610.aspxCHECKSUM()
: http://msdn.microsoft.com/en-us/library/ms189788.aspxNEWID()
: https://learn.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)
ACryptoA의. 호호 pi pi pi pi(( PI( )로 됩니다.VARBINARY(8000)
매뉴얼 페이지는 다음과 같습니다.https://learn.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sql
임의의 번호를 취득하려면 , 함수를 호출해, 필요한 타입에 캐스트 하면 됩니다.
select CAST(CRYPT_GEN_RANDOM(8) AS bigint)
'가져오기 위해'를 받습니다.float
로 +1로 하다, 할 수
select CAST(CRYPT_GEN_RANDOM(8) AS bigint) % 1000000000 / 1000000000.0
테이블 SELECT 쿼리에서 사용되는 경우 Rand() 함수는 동일한 난수를 생성합니다.Land 함수에 시드를 사용하는 경우에도 마찬가지입니다.다른 방법으로는 다음을 사용할 수 있습니다.
SELECT ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [RandomNumber]
여기서 정보를 얻었으니 문제가 잘 설명되네요.
각 행에 RAND 함수에 시드로 전달할 수 있는 정수 값이 있습니까?
1에서 14 사이의 정수를 얻으려면 다음과 같이 해야 합니다.
FLOOR( RAND(<yourseed>) * 14) + 1
매번 "같은" 랜덤 데이터를 생성하도록 시드를 보존해야 하는 경우 다음을 수행할 수 있습니다.
1. select rand()를 반환하는 뷰를 만듭니다.
if object_id('cr_sample_randView') is not null
begin
drop view cr_sample_randView
end
go
create view cr_sample_randView
as
select rand() as random_number
go
2. 뷰에서 값을 선택하는 UDF를 만듭니다.
if object_id('cr_sample_fnPerRowRand') is not null
begin
drop function cr_sample_fnPerRowRand
end
go
create function cr_sample_fnPerRowRand()
returns float
as
begin
declare @returnValue float
select @returnValue = random_number from cr_sample_randView
return @returnValue
end
go
3. 데이터를 선택하기 전에 rand() 함수를 시드하고 선택한 스테이트먼트에서 UDF를 사용합니다.
select rand(200); -- see the rand() function
with cte(id) as
(select row_number() over(order by object_id) from sys.all_objects)
select
id,
dbo.cr_sample_fnPerRowRand()
from cte
where id <= 1000 -- limit the results to 1000 random numbers
select round(rand(checksum(newid()))*(10)+20,2)
20달러 30초 round
이치
음수를 원할 경우 다음과 같이 할 수 있습니다.
select round(rand(checksum(newid()))*(10)-60,2)
그러면 최소값은 -60, 최대값은 -50이 됩니다.
LAND(seedInt)에서 시드 값을 사용해 보십시오.RAND()는 스테이트먼트당 1회만 실행되므로 매번 같은 번호가 표시됩니다.
의 임의의할 수 .newid()
SELECT table_name, newid() magic_number
FROM information_schema.tables
각 행에 대해 LAND()를 호출해야 합니다.여기 좋은 예가 있다
내가 선택한 "Answer"에 대해 가끔 겪는 문제는 분포가 항상 고르지 않다는 것이다.많은 행에서 랜덤 1~14의 균등한 분포가 필요한 경우 다음과 같은 작업을 수행할 수 있습니다(데이터베이스에는 511개의 테이블이 있으므로 이 작업이 가능합니다).행 수가 난수 범위보다 적은 경우, 이것은 올바르게 동작하지 않습니다).
SELECT table_name, ntile(14) over(order by newId()) randomNumber
FROM information_schema.tables
이는 숫자의 시퀀스를 유지하고 다른 열을 랜덤화한다는 점에서 일반 랜덤 솔루션과 반대됩니다.
데이터베이스에는 511개의 테이블이 있습니다(이는 information_schema에서 선택한 b/c에만 해당).이전 쿼리를 임시 테이블 #X에 입력한 후 결과 데이터에 대해 다음 쿼리를 실행하면 다음과 같습니다.
select randomNumber, count(*) ct from #X
group by randomNumber
이 결과를 보면 랜덤 번호가 여러 행에 매우 균등하게 분포되어 있습니다.
다음과 같이 간단합니다.
DECLARE @rv FLOAT;
SELECT @rv = rand();
이렇게 하면 0~99 사이의 난수가 테이블에 표시됩니다.
CREATE TABLE R
(
Number int
)
DECLARE @rv FLOAT;
SELECT @rv = rand();
INSERT INTO dbo.R
(Number)
values((@rv * 100));
SELECT * FROM R
select ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) as [Randomizer]
항상 나를 위해 일해왔다
newid() 사용
select newid()
혹은 이것일 수도 있다
select binary_checksum(newid())
1과 14 사이의 난수를 생성하려는 경우.
SELECT CONVERT(int, RAND() * (14 - 1) + 1)
또는
SELECT ABS(CHECKSUM(NewId())) % (14 -1) + 1
DROP VIEW IF EXISTS vwGetNewNumber;
GO
Create View vwGetNewNumber
as
Select CAST(RAND(CHECKSUM(NEWID())) * 62 as INT) + 1 as NextID,
'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'as alpha_num;
---------------CTDE_GENERATE_PUBLIC_KEY -----------------
DROP FUNCTION IF EXISTS CTDE_GENERATE_PUBLIC_KEY;
GO
create function CTDE_GENERATE_PUBLIC_KEY()
RETURNS NVARCHAR(32)
AS
BEGIN
DECLARE @private_key NVARCHAR(32);
set @private_key = dbo.CTDE_GENERATE_32_BIT_KEY();
return @private_key;
END;
go
---------------CTDE_GENERATE_32_BIT_KEY -----------------
DROP FUNCTION IF EXISTS CTDE_GENERATE_32_BIT_KEY;
GO
CREATE function CTDE_GENERATE_32_BIT_KEY()
RETURNS NVARCHAR(32)
AS
BEGIN
DECLARE @public_key NVARCHAR(32);
DECLARE @alpha_num NVARCHAR(62);
DECLARE @start_index INT = 0;
DECLARE @i INT = 0;
select top 1 @alpha_num = alpha_num from vwGetNewNumber;
WHILE @i < 32
BEGIN
select top 1 @start_index = NextID from vwGetNewNumber;
set @public_key = concat (substring(@alpha_num,@start_index,1),@public_key);
set @i = @i + 1;
END;
return @public_key;
END;
select dbo.CTDE_GENERATE_PUBLIC_KEY() public_key;
Update my_table set my_field = CEILING((RAND(CAST(NEWID() AS varbinary)) * 10))
1에서 10 사이의 숫자.
이것을 시험해 보세요.
SELECT RAND(convert(varbinary, newid()))*(b-a)+a magic_number
어디에a
낮은 수치와b
상위 번호입니다.
특정 수의 난수가 필요한 경우 재귀 CTE를 사용할 수 있습니다.
;WITH A AS (
SELECT 1 X, RAND() R
UNION ALL
SELECT X + 1, RAND(R*100000) --Change the seed
FROM A
WHERE X < 1000 --How many random numbers you need
)
SELECT
X
, RAND_BETWEEN_1_AND_14 = FLOOR(R * 14 + 1)
FROM A
OPTION (MAXRECURSION 0) --If you need more than 100 numbers
언급URL : https://stackoverflow.com/questions/1045138/how-do-i-generate-a-random-number-for-each-row-in-a-t-sql-select
'itsource' 카테고리의 다른 글
테이블이 존재하는지 확인하고 존재하지 않는 경우 SQL Server 2008에서 생성합니다. (0) | 2023.04.17 |
---|---|
Windows에서 260자 경로 길이 제한이 있는 이유는 무엇입니까? (0) | 2023.04.17 |
「 」의 맞추기 「 」의 맞추기 「 」의 맞추기 페이지 중앙(가로/가로)까지 (0) | 2023.04.17 |
선택 안 함 Excel vba 고정 창 (0) | 2023.04.17 |
git 풀 실행 취소, 저장소를 이전 상태로 되돌리는 방법 (0) | 2023.04.17 |