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. Create a UDF that selects the value from the view.
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. Before selecting your data, seed the rand() function, and then use the UDF in your select statement.
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 randomNumber, count(*) ct from #X
group by randomNumber
我得到了这个结果,告诉我我的随机数非常均匀地分布在很多行中:
4
select ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) as [Randomizer]
一直为我工作
4
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;
14
它很简单:
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
17 回答
你需要为每一行调用RAND() . 这是一个很好的例子
https://web.archive.org/web/20090216200320/http://dotnet.org.za/calmyourself/archive/2007/04/13/sql-rand-trap-same-value-per-row.aspx
这里的随机数将在20到30之间 .
round
将给出两位小数最大值 .如果您想要负数,您可以使用
然后最小值为-60,最大值为-50 .
看看SQL Server - Set based random numbers,其中有一个非常详细的解释 .
总而言之,以下代码生成0到13之间的随机数,包括规范化分布:
要更改范围,只需更改表达式末尾的数字即可 . 如果您需要包含正数和负数的范围,请格外小心 . 如果你做错了,可以重复数字0 .
房间里数学螺母的一个小警告:这段代码有一点点偏差 .
CHECKSUM()
导致在整个sql Int数据类型范围内统一的数字,或者至少接近我的(编辑器)测试可以显示的数字 . 但是,当CHECKSUM()在该范围的最高端产生一个数字时,会有一些偏差 . 每次在最大可能整数和所需范围大小的最后一个精确倍数(在这种情况下为14)之间得到一个数字之前,这个结果优先于你的范围的剩余部分,而不能从这是14的最后一个 .例如,假设Int类型的整个范围仅为19. 19是您可以容纳的最大可能整数 . 当CHECKSUM()得到14-19时,这些对应于结果0-5 . 这些数字将大大超过6-13,因为CHECKSUM()生成它们的可能性是其两倍 . 更直观地展示这一点 . 下面是我们想象的整数范围的整个可能结果集:
你可以在这里看到,产生一些数字的机会比其他数字更多:偏见 . 值得庆幸的是,Int类型的实际范围要大得多......以至于在大多数情况下偏差几乎检测不到 . 但是,如果您发现自己为严肃的安全代码执行此操作,则需要注意这一点 .
在单个批处理中多次调用时,rand()返回相同的数字 .
我建议使用convert(
varbinary
,newid()
)作为种子参数:newid()
保证每次调用时返回不同的值,即使在同一批次中也是如此,因此将其用作种子将提示rand()每次都给出不同的值 .编辑从1到14得到一个随机整数 .
以上将生成0到1之间的(伪)随机数,不包括 . 如果在select中使用,因为每行的种子值发生更改,它将为每一行生成一个新的随机数(但不保证每行生成一个唯一的数字) .
结合上限10(产生数字1 - 10)的示例:
Transact-SQL文档:
CAST()
:https://docs.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://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sql1000到9999之间的随机数生成:
“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因此,要获得一个随机数,您只需调用该函数并将其转换为必要的类型:
或者要获得介于-1和1之间的
float
,您可以执行以下操作:如果在表SELECT查询中使用,Rand()函数将生成相同的随机数 . 如果您将种子用于Rand函数,则同样适用 . 另一种方法是使用:
从here获得了信息,这很好地解释了问题 .
您是否可以将每行中的整数值作为种子传递给RAND函数?
要获得1到14之间的整数,我相信这会起作用:
如果你需要保存你的种子,以便它产生每次“相同”的随机数据,您可以执行以下操作:
1. Create a view that returns select rand()
2. Create a UDF that selects the value from the view.
3. Before selecting your data, seed the rand() function, and then use the UDF in your select statement.
尝试在RAND(seedInt)中使用种子值 . RAND()每个语句只执行一次,这就是每次看到相同数字的原因 .
如果你不需要它是一个整数,但任何随机的唯一标识符,你可以使用
newid()
选择newid()
或者可能这个选择binary_checksum(newid())
我选择的“答案”有时会遇到的问题是分布并不总是均匀 . 如果你需要在很多行之间非常均匀地分配随机的1 - 14,你可以做这样的事情(我的数据库有511个表,所以这很有用 . 如果你的行数少于你的随机数 Span ,这不起作用好):
这种方式与正常的随机解决方案相反,它保持数字排序并随机化另一列 .
记住,我的数据库中有511个表(只有b / c才能从information_schema中选择) . 如果我将上一个查询放入临时表#X中,然后对结果数据运行此查询:
我得到了这个结果,告诉我我的随机数非常均匀地分布在很多行中:
一直为我工作
它很简单:
这将把0-99之间的随机数放入表中: