我正在试图弄清楚如何在我的一个表中为每个记录(行)分配一个在SQL Server 2008中0到1之间的唯一编号(值)。我已经查看了rand(校验和(newid()) )类型方法,这似乎是合适的,除了我需要我的一组值是可重现的(即如果我多次运行相同的查询,我会得到相同的随机值)。
知道如何解决这个问题吗?
答案 0 :(得分:1)
就像在评论中已经提到过的那样,你可以获得随机数或你得到的“某些”数字,这些数字看起来是随机的,但每次都可以重新创建。
如果你只需要0或1,你可以做这样的事情。
SELECT ABS(CONVERT(BIGINT, HASHBYTES('SHA1', name)) % 2)
FROM sys.objects
通过使用Mudolo %
函数,您将只获得0,1,-1。比你用ABS
绝对值包装它只得到1和0.
我希望这会让你朝着正确的方向前进。您可以在此处了解HASHBYTES
此处http://technet.microsoft.com/en-us/library/ms174415.aspx,您可以尝试使用不同的可用算法。
答案 1 :(得分:1)
您需要一次循环一行,以获得每行的不同随机值。为了确保每次都是相同的随机序列,选择一个固定的种子,然后用该种子调用RAND(种子)一次。之后对RAND()的每次调用(在同一个会话中)将为您提供该种子的序列号,并且将始终为给定的种子生成相同的序列。
有不同的循环方式(例如使用光标),但这里有一个让你入门。
create table RandomValues
(
Id int,
RandomValue float
)
go
-- Pick a value and always use the same one to get reproducible random numbers
declare @FixedSeed int
set @FixedSeed = 100
declare @Id int
declare @MaxId int
select @MaxId = MAX(Id), @Id = MIN(Id) from OriginalData
-- You don't need this value for anything, you just need a call to rand(@FixedSeed)
-- to start the sequence with the fixed seed
declare @dummyseed float
set @dummyseed = rand(@FixedSeed)
while (@Id <= @MaxId)
begin
insert RandomValues
select Id, rand()
from OriginalData
where Id = @Id
-- Get the next Id from the original table
select @Id = MIN(Id)
from OriginalData
where Id > @Id
end
select od.*, rv.RandomValue
from RandomValues rv
join OriginalData od on rv.Id = od.Id
答案 2 :(得分:0)
正如许多人已经建议的那样,随机数的查找表怎么样。如果主表具有整数键,则可以使用以下代码生成合适的查找表;
;with t as (
select 1 as i
union all
select i + 1
from t
where i < 1000) -- adjust accordingly
select
i,
cast(abs(checksum(newid())) / 2147483647.0 as float) as r -- the RAND function returns a float.
into dbo.RandomNumbers
from
t
option(maxrecursion 0)
如果您不想沿着查找路线走下去,那么您需要一个能够返回可重复随机数的函数。我尝试了一些不同的东西并提出了rand(checksum(i,1.0/i))
。它仍然需要一个整数键。
;with t as (
select 1 as i
union all
select i+1
from t
where i<1000) -- adjust accordingly
select
i,
rand(checksum(i,1.0/i)) as r
from
t
option(maxrecursion 0)
请注意,上述两个想法都没有解决您问题的独特方面,我没有分析数字的分布情况,但这些数字的重要程度取决于您的工作。
里斯