How do I generate random number for each row in a

2018-12-31 10:30发布

I need a different random number for each row in my table. The following seemingly obvious code uses the same random value for each row.

SELECT table_name, RAND() magic_number 
FROM information_schema.tables 

I'd like to get an INT or a FLOAT out of this. The rest of the story is I'm going to use this random number to create a random date offset from a known date, e.g. 1-14 days offset from a start date.

This is for Microsoft SQL Server 2000.

17条回答
裙下三千臣
2楼-- · 2018-12-31 11:09

Do you have an integer value in each row that you could pass as a seed to the RAND function?

To get an integer between 1 and 14 I believe this would work:

FLOOR( RAND(<yourseed>) * 14) + 1
查看更多
不再属于我。
3楼-- · 2018-12-31 11:10

If you need to preserve your seed so that it generates the "same" random data every time, you can do the following:

1. Create a view that returns select rand()

if object_id('cr_sample_randView') is not null
begin
    drop view cr_sample_randView
end
go

create view cr_sample_randView
as
select rand() as random_number
go

2. Create a UDF that selects the value from the view.

if object_id('cr_sample_fnPerRowRand') is not null
begin
    drop function cr_sample_fnPerRowRand
end
go

create function cr_sample_fnPerRowRand()
returns float
as
begin
    declare @returnValue float
    select @returnValue = random_number from cr_sample_randView
    return @returnValue
end
go

3. Before selecting your data, seed the rand() function, and then use the UDF in your select statement.

select rand(200);   -- see the rand() function
with cte(id) as
(select row_number() over(order by object_id) from sys.all_objects)
select 
    id,
    dbo.cr_sample_fnPerRowRand()
from cte
where id <= 1000    -- limit the results to 1000 random numbers
查看更多
弹指情弦暗扣
4楼-- · 2018-12-31 11:10

If you don't need it to be an integer, but any random unique identifier, you can use newid()

SELECT table_name, newid() magic_number 
FROM information_schema.tables
查看更多
皆成旧梦
5楼-- · 2018-12-31 11:10
select ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) as [Randomizer]

has always worked for me

查看更多
时光乱了年华
6楼-- · 2018-12-31 11:14

The problem I sometimes have with the selected "Answer" is that the distribution isn't always even. If you need a very even distribution of random 1 - 14 among lots of rows, you can do something like this (my database has 511 tables, so this works. If you have less rows than you do random number span, this does not work well):

SELECT table_name, ntile(14) over(order by newId()) randomNumber 
FROM information_schema.tables

This kind of does the opposite of normal random solutions in the sense that it keeps the numbers sequenced and randomizes the other column.

Remember, I have 511 tables in my database (which is pertinent only b/c we're selecting from the information_schema). If I take the previous query and put it into a temp table #X, and then run this query on the resulting data:

select randomNumber, count(*) ct from #X
group by randomNumber

I get this result, showing me that my random number is VERY evenly distributed among the many rows:

enter image description here

查看更多
登录 后发表回答