不使用NewID的SQL上的随机数()

时间:2010-02-11 20:39:40

标签: sql sql-server tsql random

您好我想使用以下语句生成一个唯一随机数:

Convert(int, (CHECKSUM(NEWID()))*100000) AS [ITEM] 

当我在“from”上使用连接子句时,它会使用NEWID()

生成双重寄存器

我正在使用SQL Server 2000

* PD:当我使用Rand()时,它可能会重复1次100,000的概率,但这是非常重要的,所以它必须是重复生成随机值的概率的0%

My Query with NewID()和SELECT语句的结果是重复的(x2) 我的QUery没有NewID()并且在SELECT语句中使用Rand()是单个(x1)但重复生成的随机值的概率是不确定的,但存在!

谢谢!

6 个答案:

答案 0 :(得分:9)

它是否溢出?

CAST(CHECKSUM(NEWID()) AS bigint) * CAST(100000 AS bigint) AS [ITEM]

CAST(CAST(CHECKSUM(NEWID()) AS bigint) * CAST(100000 AS bigint) % 2100000000 AS int) AS [ITEM]

编辑:

没有0%重复次数的可能性

CHECKSUM(NEWID()))返回一个有40亿行的整数。 birthday paradox意味着碰撞的可能性要高得多。

Bigint(上图)或小数(38,0)为您提供了更多的空间,但只能减少碰撞的几率,但绝不会消除。

但仍然不明白你为什么要尝试加入一个独特的随机数...

答案 1 :(得分:1)

答案 2 :(得分:0)

在SQL Server中,您可以使用它来生成随机数,或指定参数之间的随机整数

DECLARE @RandomNumber float
DECLARE @RandomInteger int
DECLARE @MaxValue int
DECLARE @MinValue int

SET @MaxValue = 4
SET @MinValue = 2

SELECT @RandomNumber = RAND()

SELECT @RandomInteger = ((@MaxValue + 1) - @MinValue) * @RandomNumber + @MinValue

SELECT @RandomNumber as RandomNumber, @RandomInteger as RandomInteger

答案 3 :(得分:0)

如果你正在使用MySQL

 SELECT RAND();

MySQL doc: http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand

如果你正在使用Postgres

SELECT RANDOM();

Postgres doc: http://www.postgresql.org/docs/8.0/static/functions-math.html

答案 4 :(得分:0)

使用一位数字更新列

update  [dbo].[AccomodationRatings]
set Rate =rand(CHECKSUM(NEWID()))*10
WHERE Rate >0

答案 5 :(得分:0)

好吧,所以首先,如果您不想使用“ NEWID”函数来生成随机数,则可以使用“ RAND”函数,类似这样的操作是随机的:

SELECT CAST(ROUND((RAND() - .5) * 2147483647, 0) AS INT)

如果您需要BIGINT,请将其强制转换为BIGINT,但是请记住,这只会为您提供INT的熵(和Range):

SELECT CAST(ROUND((RAND() - .5) * 2147483647, 0) AS BIGINT)

所有其他答案都将返回BIGINT,我建议使用“ NEWID”函数,但是我会做不同的事情。例如,如果您做任何变体,都使用一个“ CHECKSUM(NEWID())AS bigint)”然后返回一个BIGINT,那么您只有INT的熵,而不是BIGINT的熵,而是尝试使用两个: / p>

SELECT CAST(CAST(CHECKSUM(NEWID()) AS BINARY(4)) + CAST(CHECKSUM(NEWID()) AS BINARY(4)) AS BIGINT)

我想,如果您真的不喜欢“ NEWID”功能,也可以使用“ RAND”来做到这一点:

SELECT CAST(CAST(ROUND((RAND() - .5) * 2147483647, 0) AS BINARY(4)) + CAST(ROUND((RAND() - .5) * 2147483647, 0) AS BINARY(4)) AS BIGINT)

现在,这应该(或多或少)为您提供BIGINT的熵,当然,它可能并不完美,而且我还没有证明它是否会产生均匀分布,因此请谨慎使用。

如果确实要确保给定的ID是唯一的,则需要使用GUID或GUID等效项,如果生成的值不在该范围内,则必须这样做,或者在单独的表/中跟踪生成的字段在创建ID之前先扫描表格。没有办法解决。同样,您也无法以随机方式生成两个独立值,发生碰撞的机率为0%。您可以靠近得足够近,perfectly safe though.

注意:对于那些不惧怕使用NEWID的人)我将执行以下操作,以最少的体操获得全部16字节的熵:

SELECT CAST(CAST(NEWID() AS VARBINARY(8)) AS BIGINT)