0

I'm having a problem with random values being generated for each row in a result set in SQL Server 2008. I found a similar question here, but upon implementing the proposed answer, I saw the same problem as before. When running the query I have provided below, it seems that the same values will sometimes show up in consecutive rows, even though I'm calling for a new NEWID() with each row.

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

If I change the INT to a BIGINT, as suggested in the link I provided, nothing is solved, so I don't believe that it's an "overflow" issue.

4

1 回答 1

0

如果我从选择中取出计算,我不会得到双倍的行:

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

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

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

我仍然不断地得到重复。这意味着优化器可能正在缓存/重用值,至少在选择上。对于非确定性函数调用,我认为这不合适。我在 10.0.1600 和 10.50.1600(2008 RTM 和 2008R2 RTM)上得到了类似的结果。

于 2013-05-29T22:22:46.887 回答