sql server 2008不生成随机值

时间:2013-05-24 16:22:37

标签: sql-server-2008 tsql random

我遇到了为SQL Server 2008中的结果集中的每一行生成随机值的问题。我发现了一个类似的问题here,但在实现建议的答案时,我看到了同样的问题问题和以前一样。运行我在下面提供的查询时,似乎相同的值有时会显示在连续的行中,即使我要求每行调用一个新的NEWID()

DECLARE @Id int = 0
DECLARE @Counter int = 1
DECLARE @Value int

CREATE TABLE #Table1
(
id int identity(1,1)
,Value int
)

WHILE @Counter < 100000
BEGIN
    INSERT INTO #Table1 (Value)
    SELECT CAST(RAND(CHECKSUM(NEWID())) * 100000 as INT)
    SET @Counter += 1
END

SET @Counter = 0
WHILE @Counter < 5
BEGIN
    SELECT
        @Value = T.Value
        ,@Id = T.id
    FROM #Table1 T
    WHERE T.id = CAST(RAND(CHECKSUM(NEWID())) * 100000 as INT) + 1 + @Counter

    IF @Id <> 0
        SELECT @Value AS Value ,@Id as ID
    SET @Counter += 1
END
DROP TABLE #Table1

如果我按照我提供的链接中的建议将INT更改为BIGINT,则无法解决任何问题,因此我不相信它是&#34} ;溢出&#34;问题。

1 个答案:

答案 0 :(得分:0)

如果我从select中取出计算,我不会得到加倍的行:

DECLARE @Id int = 0
DECLARE @Counter int = 1
DECLARE @Value int
-- new variable
DECLARE @DERIVED INT 

CREATE TABLE #Table1
(
id int identity(1,1)
,Value int
)

WHILE @Counter < 100000
BEGIN
    INSERT INTO #Table1 (Value)
    SELECT CAST(RAND(CHECKSUM(NEWID())) * 100000 as INT)
    SET @Counter += 1
END

SET @Counter = 0
WHILE @Counter < 5
BEGIN
--set here to remove calculation from the select
    SET @DERIVED = CAST(RAND(CHECKSUM(NEWID())) * 100000 as INT) + 1 + @Counter;
    SELECT
        @Value = T.Value
        ,@Id = T.id
    FROM #Table1 T
    WHERE T.id = @DERIVED

    IF @Id <> 0
        SELECT @Value AS Value ,@Id as ID;
    SET @Counter += 1
END
DROP TABLE #Table1

我每次都会在select中使用伪随机生成器看到重复项。奇怪的是,无论计算是否在插入...选择内,我在插入循环上得到的重复频率都相同。这可能是巧合,因为我们正在处理随机选择的数字。另请注意,由于您要添加伪随机结果,因此结果在技术上不重复。他们是下降序列:

11111 + 1 + 1 = 11113
11110 + 1 + 2 = 11113

相同的整体结果,不同的伪随机结果。但是,如果我改变

CAST(RAND(CHECKSUM(NEWID())) * 100000 as INT) + 1 + @Counter

CAST(RAND(CHECKSUM(NEWID())) * 100000 as INT) + @Counter + @Counter

我仍然一直都是重复的。这意味着优化器可能正在缓存/重新使用值,至少在select上。我称之为非确定性函数调用是不合适的。我在10.0.1600和10.50.1600(2008 RTM和2008R2 RTM)上得到了类似的结果。