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