我有一条语句,它根据一个随机值和另一个值将值插入表中
INSERT INTO TRAINER_SYNC (Steps, TrainerId, SyncDate)
SELECT AverageSteps * (RAND()*(1.15-0.85)+0.85), Id, GETDATE()
FROM TRAINER
这很好,但是只要两个“ Trainers”具有相同的“ AverageSteps”,插入表中的数字就始终相同。
例如,如果所有培训师的平均步数为10000
,则这是TRAINER_SYNC
表中的结果
Id TrainerId SyncDate Steps
10 1 2018-10-20 18:42:16.407 9482
11 2 2018-10-20 18:42:16.407 9482
12 3 2018-10-20 18:42:16.407 9482
13 4 2018-10-20 18:42:16.407 9482
14 5 2018-10-20 18:42:16.407 9482
15 6 2018-10-20 18:42:16.407 9482
16 7 2018-10-20 18:42:16.407 9482
17 8 2018-10-20 18:42:16.407 9482
18 9 2018-10-20 18:42:16.407 9482
有没有一种方法可以使插入语句中的RAND()
更加“随机”?我不知道它叫什么,但是重置初始种子,以便插入的每次迭代都给我一个不同的随机值?
答案 0 :(得分:0)
您可以使用
1)
RAND(CHECKSUM(NEWID()))
OR
2)
INSERT INTO TRAINER_SYNC (Steps, TrainerId, SyncDate)
SELECT AverageSteps * (RAND(AverageSteps)*(1.15-0.85)+0.85), Id, GETDATE()
FROM TRAINER
答案 1 :(得分:0)
rand()
是一类特殊的函数,对于SQL语句中的每个调用,该函数仅被评估一次。这可能确实令人困惑,因为:
select rand(), rand()
返回两个不同的值。但是,
select rand(), rand()
from (values (1), (2), (3)) v(x)
返回三行-每行具有相同的两个值。这是SQL Server的优化“功能”。我相信getdate()
(和类似的日期/时间函数)是唯一具有此行为的其他函数。
通常的解决方案是将newid()
植入随机数生成器。但是,返回类型不同,因此checksum()
用于将id
转换为数字:
INSERT INTO TRAINER_SYNC (Steps, TrainerId, SyncDate)
SELECT AverageSteps * (RAND(CHECKSUM(NEWID()))*(1.15-0.85)+0.85),
Id, GETDATE()
FROM TRAINER;
您可以使用其他种子(如果有)。例如,如果每个培训师只参加一行,则可以使用rand(id)
。我应该注意,rand()
并不是特别具有种子“随机性”,因此相邻种子通常会产生相似的数字。
您可能不应该在GETDATE()
中设置INSERT
。您可以使用以下方法创建表:
SyncDate datetime default getdate()
因此默认值为插入时间。