我遇到了为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;问题。
答案 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)上得到了类似的结果。