我想的结果,在可重复的方式,用于诸如寻呼随机排序。对于此NEWID()是在被重新获得,相同的结果不能太随机的。兰德(种子)令将是理想的使用相同的种子会导致相同的随机集合。不幸的是,兰德()状态复位每行,没有人有一个解决方案?

declare @seed as int;
set @seed = 1000;

create table temp (
id int,
date datetime)

insert into temp (id, date) values (1,'20090119')
insert into temp (id, date) values (2,'20090118')
insert into temp (id, date) values (3,'20090117')
insert into temp (id, date) values (4,'20090116')
insert into temp (id, date) values (5,'20090115')
insert into temp (id, date) values (6,'20090114')

-- re-seeds for every item
select *, RAND(), RAND(id+@seed) as r from temp order by r
--1 2009-01-19 00:00:00.000 0.277720118060575   0.732224964471124
--2 2009-01-18 00:00:00.000 0.277720118060575   0.732243597442382
--3 2009-01-17 00:00:00.000 0.277720118060575   0.73226223041364
--4 2009-01-16 00:00:00.000 0.277720118060575   0.732280863384898
--5 2009-01-15 00:00:00.000 0.277720118060575   0.732299496356156
--6 2009-01-14 00:00:00.000 0.277720118060575   0.732318129327415
-- Note how the last column is +=~0.00002

drop table temp

-- interestingly this works:
select RAND(@seed), RAND()
--0.732206331499865 0.306382810665955

请注意,我试图兰德(ID),但只是原来进行排序。显然兰德(n)的<兰特(N + 1)

有帮助吗?

解决方案

建筑关闭gkrogers哈希建议的这个伟大工程。对性能有什么想法?

declare @seed as int;
set @seed = 10;

create table temp (
id int,
date datetime)

insert into temp (id, date) values (1,'20090119')
insert into temp (id, date) values (2,'20090118')
insert into temp (id, date) values (3,'20090117')
insert into temp (id, date) values (4,'20090116')
insert into temp (id, date) values (5,'20090115')
insert into temp (id, date) values (6,'20090114')

-- re-seeds for every item
select *, HASHBYTES('md5',cast(id+@seed as varchar)) r
from temp order by r
--1 2009-01-19 00:00:00.000 0x6512BD43D9CAA6E02C990B0A82652DCA
--5 2009-01-15 00:00:00.000 0x9BF31C7FF062936A96D3C8BD1F8F2FF3
--4 2009-01-16 00:00:00.000 0xAAB3238922BCC25A6F606EB525FFDC56
--2 2009-01-18 00:00:00.000 0xC20AD4D76FE97759AA27A0C99BFF6710
--3 2009-01-17 00:00:00.000 0xC51CE410C124A10E0DB5E4B97FC2AF39
--6 2009-01-14 00:00:00.000 0xC74D97B01EAE257E44AA9D5BADE97BAF

drop table temp

编辑:注意,的@seed因为它是在查询使用可以用一个参数或具有恒定INT被更换,如果使用动态SQL声明。 (在一个TSQL方式@int的声明是不是必需的)

其他提示

可以使用的值,从各行重新评估rand函数:

Select *, Rand(@seed + id) as r from temp order by r

添加ID确保兰特补种对于每一行。但是,对于种子的价值,你总是会得到回行的相同的顺序(前提是该表不发生变化)

创建散列可以是更多的时间比创建一个种子随机耗时。

要得到在RAND的可能输出更多的变化([种子]),则需要以使[种子]显著太变化。可能如...

SELECT
    *,
    RAND(id * 9999)    AS [r]
FROM
   temp
ORDER BY
   r

使用恒定,确保你问的可复制性。但是,如果你希望你的表变得足够大要小心(ID * 9999),导致溢出的结果...

SELECT *, checksum(id) AS r FROM table ORDER BY r

这样的作品。虽然从校验和()的输出不举目皆是随机给我。的 MSDN文档规定:

  

[...],我们不建议使用校验和检测值是否已经改变,除非你的应用程序可以容忍偶尔丢失的变化。考虑使用替代HASHBYTES。当指定的MD5散列算法,HASHBYTES返回为两个不同的输入相同的结果的概率比CHECKSUM的低得多。

,而可以是其更快。

做一些阅读本是一个公认的方法之后。

Select Rand(@seed) -- now rand is seeded

Select *, 0 * id + Rand() as r from temp order by r

ID为在表达导致它被重新评估每一行。但由0乘以它确保它不不影响兰特的结果。

什么做事情的可怕的方式!

这工作很适合我,在过去,它可以适用于任何表格(只是在ORDER BY子句螺栓):

SELECT *
FROM MY_TABLE
ORDER BY  
  (SELECT ABS(CAST(NEWID() AS BINARY(6)) % 1000) + 1);
create table temp (
id int,
date datetime)

insert into temp (id, date) values (1,'20090119')
insert into temp (id, date) values (2,'20090118')
insert into temp (id, date) values (3,'20090117')
insert into temp (id, date) values (4,'20090116')
insert into temp (id, date) values (5,'20090115')
insert into temp (id, date) values (6,'20090114')

-- re-seeds for every item
select *, NEWID() r
from temp order by r

drop table temp
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top