I\'m running a SQL query on SQL Server 2005, and in addition to 2 columns being queried from the database, I\'d also like to return 1 column of random numbers along with the
Adam's answer works really well, so I marked it as accepted. While I was waiting for an answer though, I also found this blog entry with a few other (slightly less random) methods. Kaboing's method was among them.
http://blog.sqlauthority.com/2007/04/29/sql-server-random-number-generator-script-sql-query/
Query
select column1, column2, cast(new_id() as varchar(10)) as column3
from table1
I realize this is an older post... but you don't need a view.
select column1, column2,
ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 10000 as column3
from table1
This snippet seems to provide a reasonable substitute for rand() in that it returns a float between 0.0 and 1.0. It uses only the last 3 bytes provided by newid() so total randomness may be slightly different than the conversion to VARBINARY then INT then modding from the recommended answer. Have not had a chance to test relative performance but seems fast enough (and random enough) for my purposes.
SELECT CAST(SubString(CONVERT(binary(16), newid()), 14, 3) AS INT) / 16777216.0 AS R
WARNING
Adam's answer involving the view is very inefficient and for very large sets can take out your database for quite a while, I would strongly recommend against using it on a regular basis or in situations where you need to populate large tables in production.
Instead you could use this answer.
Proof:
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 trace:
alt text http://img519.imageshack.us/img519/8425/destroydbxu9.png
This is proof that stuff is random enough for numbers between 0 to 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
newid() i believe is very resource intensive. i recall trying that method on a table of a few million records and the performance wasn't nearly as good as rand().