不使用 NewID() 的 SQL 随机数

问题描述 投票:0回答:7

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

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),但重复生成的随机值的概率不确定,但存在!

谢谢!

sql sql-server t-sql random
7个回答
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 亿行。 生日悖论意味着碰撞的可能性当然要高得多。

Bigint(上图)或decimal(38,0)给你更多的发挥空间,但只会减少碰撞的机会,但永远不会消除。

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


1
投票

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

0
投票

好的,所以首先如果你不想使用“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) 

0
投票

这里是基本公式

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

-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


-1
投票

用个位数更新列

update  [dbo].[AccomodationRatings]
set Rate =rand(CHECKSUM(NEWID()))*10
WHERE Rate >0
© www.soinside.com 2019 - 2024. All rights reserved.