您好,我想生成一个唯一的随机数,而不使用以下语句:
Convert(int, (CHECKSUM(NEWID()))*100000) AS [ITEM]
因为当我在“from”上使用连接子句时,它会使用 NEWID() 生成双寄存器
我使用 SQL Server 2000
*PD:当我使用 Rand() 时,它可能会以 100000000 的概率 1 重复,但这非常关键,因此重复生成的随机值的概率必须为 0%
我的 NewID() 查询和 SELECT 语句的结果重复 (x2) 我的 QUEry 没有 NewID() 并在 SELECT 语句上使用 Rand() 是单个 (x1),但重复生成的随机值的概率不确定,但存在!
谢谢!
溢出了吗?
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 亿行。 生日悖论意味着碰撞的可能性当然要高得多。
Bigint(上图)或decimal(38,0)给你更多的发挥空间,但只会减少碰撞的机会,但永远不会消除。
但仍然不明白为什么你要尝试以唯一的随机数加入......
请参阅此处:SQL Server - 基于随机数的设置
在 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
好的,所以首先如果你不想使用“NEWID”函数来生成随机数,那么你可以使用“RAND”函数,这样的东西是随机的:
SELECT CAST(ROUND((RAND() - .5) * 2147483647, 0) AS INT)
如果您需要 BIGINT,请将其转换为 BIGINT,但请记住,它只会为您提供 INT 的熵(和范围):
SELECT CAST(ROUND((RAND() - .5) * 2147483647, 0) AS BIGINT)
所有这些其他答案都返回 BIGINT,因为我建议使用“NEWID”函数,但我会采取不同的做法。例如,如果您执行使用一个“CHECKSUM(NEWID()) AS bigint)”的任何变体,然后返回一个 BIGINT,则您只有 INT 的熵,而不是 BIGINT 之一,而是尝试使用两个:
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% 的碰撞几率随机生成两个独立的值。不过,您可以靠得足够近,绝对安全。
(注意:对于那些不害怕使用NEWID的人)我会执行以下操作,以最少的体操获得完整的16字节熵:
SELECT CAST(CAST(NEWID() AS VARBINARY(8)) AS BIGINT)
这里是基本公式
CAST(ABS(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT)) AS BIGINT)
和测试程序
Declare @_X_X table(A BigInt)
Declare @K int=100000
While @K>0
Begin
Insert into @_X_X Select CAST(ABS(CAST(CAST(NEWID() AS VARBINARY) AS BIGINT)) AS BIGINT)
Set @K=@K-1;
End
Select A,Count(1)
From @_X_X
Group By A
Having Count(1)>1
如果您使用MySQL
SELECT RAND();
MySQL 文档: http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand
如果您使用 Postgres
SELECT RANDOM();
Postgres 文档: http://www.postgresql.org/docs/8.0/static/functions-math.html
用个位数更新列
update [dbo].[AccomodationRatings]
set Rate =rand(CHECKSUM(NEWID()))*10
WHERE Rate >0