如何在SQL Server 2005中将随机数作为列返回?

时间:2008-09-18 17:50:38

标签: sql sql-server sql-server-2005 random

我在SQL Server 2005上运行SQL查询,除了从数据库中查询2列之外,我还想随机返回1列随机数。我试过这个:

select column1, column2, floor(rand() * 10000) as column3 
from table1

哪种方法有效,但问题是此查询在每一行上返回相同的随机数。每次运行查询时它都是一个不同的数字,但它不会因行而异。我怎么能这样做并为每一行获得一个新的随机数?

12 个答案:

答案 0 :(得分:40)

我意识到这是一篇较旧的帖子......但你不需要视图。

select column1, column2, 
  ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as column3 
from table1

答案 1 :(得分:4)

警告

涉及视图的

Adam's answer非常低效,对于非常大的集合可能会花费你的数据库很长一段时间,我强烈建议不要定期使用它,或者在需要填充大表的情况下使用它在生产中。

相反,您可以使用this answer

证明:

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

go 

CREATE FUNCTION RandNumber()
RETURNS float
AS
  BEGIN
  RETURN (SELECT RandNumber FROM vRandNumber)
  END

go 

create table bigtable(i int)

go 

insert into bigtable 
select top 100000 1 from sysobjects  a
join sysobjects b on 1=1

go 

select cast(dbo.RandNumber() * 10000 as integer) as r into #t from bigtable 
-- CPU (1607) READS (204639) DURATION (1551)

go

select ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as r  into #t1 
from bigtable
-- Runs 15 times faster - CPU (78) READS (809) DURATION (99)

Profiler跟踪:

alt text http://img519.imageshack.us/img519/8425/destroydbxu9.png

这证明了东西足够随机,可用于0到9999之间的数字

-- proof that stuff is random enough 
select avg(r) from #t
-- 5004
select STDEV(r) from #t
-- 2895.1999 

select avg(r) from #t1
-- 4992
select STDEV(r) from #t1
-- 2881.44 


select r,count(r) from #t
group by r 
-- 10000 rows returned 

select r,count(r) from #t1
group by r 
-- 10000 row returned 

答案 2 :(得分:3)

Adam的回答非常有效,所以我将其标记为已接受。虽然我在等待答案,但我还发现了这个博客条目以及其他一些(稍微不那么随机)的方法。 Kaboing的方法就在其中。

http://blog.sqlauthority.com/2007/04/29/sql-server-random-number-generator-script-sql-query/

答案 3 :(得分:3)

select RAND(CHECKSUM(NEWID()))

答案 4 :(得分:1)

您需要使用UDF

第一

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

第二

CREATE FUNCTION RandNumber()
RETURNS float
AS
  BEGIN
  RETURN (SELECT RandNumber FROM vRandNumber)
  END

试验:

SELECT dbo.RandNumber(), *
FROM <table>

以上借鉴Jeff's SQL Server Blog

答案 5 :(得分:1)

对于SQLServer,有几个选项 1.一个while循环,用一次一个随机数更新空列
2. .net程序集,包含一个返回随机数的函数

答案 6 :(得分:1)

<强>查询

select column1, column2, cast(new_id() as varchar(10)) as column3 
from table1

答案 7 :(得分:1)

您可能想考虑使用newid函数生成UUID而不是随机数。这些保证在每次生成时都是唯一的,而很有可能在一个简单的随机数下会发生一些重复(并且取决于你使用它的原因可能会在以后的某个时候给你一个难以调试的错误)

答案 8 :(得分:1)

newid()我认为是非常耗费资源的。我记得在几百万条记录的表格上尝试这种方法,而且性能不如rand()。

答案 9 :(得分:1)

根据我的测试,上面的答案不会产生10000的值。当您生成1到10000之间的随机数时,这可能不是什么大问题,但是1到5之间的相同算法将是显而易见的。将1添加到您的mod。

答案 10 :(得分:1)

此代码段似乎为rand()提供了合理的替代,因为它返回0.0到1.0之间的浮点数。它仅使用newid()提供的最后3个字节,因此总随机性可能与转换为VARBINARY然后INT稍有不同,然后从推荐答案进行修改。没有机会测试相对表现但看起来足够快(并且足够随机)用于我的目的。

SELECT CAST(SubString(CONVERT(binary(16), newid()), 14, 3) AS INT) / 16777216.0 AS R

答案 11 :(得分:1)

我使用c#来处理随机数。它更清洁。我有一个函数用于返回随机数列表和一个唯一键,然后我只是在行号上加入uniqueKey。因为我使用c#,我可以很容易地指定随机数必须落在的范围内。

以下是制作该功能的步骤: http://www.sqlwithcindy.com/2013/04/elegant-random-number-list-in-sql-server.html

以下是我的查询结果如下:

SELECT 
   rowNumber, 
   name, 
   randomNumber
FROM dbo.tvfRandomNumberList(1,10,100) 
INNER JOIN (select ROW_NUMBER() over (order by int_id) as 'rowNumber', name from client        
            )as clients
ON clients.rowNumber = uniqueKey