这是为每条记录生成随机数的好方法还是坏方法?

时间:2009-09-16 16:04:42

标签: sql sql-server tsql sql-server-2000 random

我的一位同事在SQL Server中发现了一个我不知道的行为。

CREATE VIEW dbo.vRandNumber AS
SELECT RAND() as RandNumber
GO

CREATE FUNCTION dbo.RandNumber() RETURNS float AS
RETURN (SELECT RandNumber FROM vRandNumber)
GO

DECLARE @mytable TABLE (id INT)
INSERT INTO @mytable SELECT 1
INSERT INTO @mytable SELECT 2
INSERT INTO @mytable SELECT 3

SELECT *, dbo.RandNumber() FROM @mytable

这个似乎是为数据集中的每条记录生成“随机”值的最快方法。但我不能完全确定这是否是记录在案的行为的结果,或者是利用巧合的奇异融合。

会使用这样的内容吗?


修改

这不是关于RAND()函数本身的优点的问题,而是使用UDF / VIEW组合来强制它在每一行上重新计算。 (在最终查询中使用RAND()而不是dbo.RandNumber(),将为每条记录提供相同的值。)

此外,关键是每次看时它的值都不同。因此,例如,可以随机选择记录。

修改

对于SQL Server 2000 +。

5 个答案:

答案 0 :(得分:3)

对于我希望继续使用未来版本的SQL Server的软件,我不会这样做。我找到了一种方法,可以为select语句中的每一行返回RAND()的不同值。这个发现是1)有点破解和2)是在SQL Server 2005上制作的。它不再适用于SQL Server 2008.这种经历让我更加依赖于欺骗来让rand()返回一个随机值行。

另外,我相信允许SQL Server优化掉对UDF的多次调用......虽然这可能会改变,因为它们现在允许一些非确定性函数。

仅对于SQL Server 2005,一种强制rand()在select语句中每行执行的方法。 不适用于SQL Server 2008。未在2005年之前的任何版本上测试过:

create table #t (i int)
insert into #t values (1)
insert into #t values (2)
insert into #t values (3)

select i, case when i = 1 then rand() else rand() end as r
from #t

1   0.84923391682467
2   0.0482397143838935
3   0.939738172108974

另外,我知道你说你不是在询问rand()的随机性,但我会很好地参考:http://msdn.microsoft.com/en-us/library/aa175776(SQL.80).aspx。它将rand()与newid()和rand(FunctionOf(PK,当前日期时间))进行比较。

答案 1 :(得分:1)

这取决于您需要的随机值。它还取决于您需要INTEGERVARCHAR等值的格式。

如果我需要随机排序行,我会做类似

的行
SELECT *
FROM [MyTable]
ORDER BY newID()

同样,您可以使用SQL Server的标识“功能”生成ints表,并执行类似的查询,并且可以为您提供随机数。

我的同事每行需要一个随机整数,因此他在我们的表中添加了一个计算字段,并在查询中返回每行生成一个随机数(整数)。我不确定我推荐这个;它在某些工具中引起了问题,但它为每个表提供了随机整数。然后,我们可以将newid()和该表的解决方案结合起来,并在需要时获取一组随机数。

所以我回到它取决于。你能详细说明你需要它吗?

更新:以下是我的同事过去使用计算列返回每行不同随机数的表定义代码段,每次查询表时都会显示:

CREATE TABLE [dbo].[Table](
    -- ...
    [OrderID] [smallint] NOT NULL,  --Not sure what happens if this is null
    -- ...
    [RandomizeID]  AS (convert(int,(1000 * rand(([OrderID] * 100 * datepart(millisecond,getdate())))))),
    -- ...
)

答案 2 :(得分:0)

如果我必须为SQL中的每一行选择一个随机数,你可以向我证明RAND()正在生成真正的随机数......

是。我可能会使用类似的东西。

答案 3 :(得分:0)

我不会用这个。据我所知,RAND()使用系统时间作为种子,并在彼此之后快速执行多次时生成相同的值。例如,试试这个:

SELECT    *, 
          RAND()
FROM      SomeTable

RAND()会为每行提供相同的值。

答案 4 :(得分:0)

对我来说,视图和udf方法很笨拙:多余的琐碎对象使用有缺陷的函数。

我使用CHECKSUM(NEWID())生成随机数(而非RAND() * xxx)或新的SQL Server 2008 CRYPT_GEN_RANDOM