1

我想使用种子在我的表中添加一个带有随机数的列。如果我使用兰德:

select *, RAND(5) as random_id from myTable

我在 random_id 列中为所有行获得了相等的值(例如 0.943597390424144)。我希望每一行的这个值都不同 - 并且每次我将传递它 0.5 值(例如),它将再次是相同的值(因为种子应该工作......)。

我怎样才能做到这一点?

(例如,在 PostrgreSql 中我可以写

SELECT setseed(0.5); SELECT t.* , random() as random_id FROM myTable t

我会在每一行中得到不同的值。)


编辑:

在我看到这里的评论之后,我设法以某种方式解决了这个问题 - 但它根本没有效率。如果有人知道如何改进它 - 它会很棒。如果没有 - 我将不得不找到另一种方式。

我在这里使用了示例的基本思想。

创建具有空白种子值的临时表:

select * into t_myTable  from (
select t.*, -1.00000000000000000 as seed
       from myTable t
       ) as temp

为每个种子值添加一个随机数,一次一行(这是不好的部分......):

USE CPatterns;
GO
DECLARE @seed float;
DECLARE @id int;
DECLARE VIEW_CURSOR CURSOR FOR
select id
from t_myTable t;
OPEN VIEW_CURSOR;
FETCH NEXT FROM VIEW_CURSOR
into @id;
set @seed = RAND(5);

WHILE @@FETCH_STATUS = 0
   BEGIN
      set @seed = RAND();
         update t_myTable set seed = @seed where id = @id

      FETCH NEXT FROM VIEW_CURSOR
         into @id;

   END;
CLOSE VIEW_CURSOR;
DEALLOCATE VIEW_CURSOR;
GO

使用种子值创建视图并按其排序

create view my_view AS 
select row_number() OVER (ORDER BY seed, id) AS  source_id ,t.*
       from t_myTable t
4

4 回答 4

1

我认为在表中获取可重复随机 id 的最简单方法是在每一行上使用row_number()或固定。id让我假设您有一个名为id每行具有不同值的列。

这个想法只是将其用作种子:

select rand(id*1), as random_id
from mytable;

请注意,id 的种子是整数而不是浮点数。如果你想要一个浮点种子,你可以做一些事情checksum()

select rand(checksum(id*0.5)) as random_id
. . .

如果您这样做是为了采样(random_id < 0.1例如,您会说 10% 的样本,那么我经常在 上使用模运算row_number()

with t as (
      select t.* row_number() over (order by id) as seqnum
      from mytable t
     )
select *
from t
where ((seqnum * 17 + 71) % 101) < 0.1

这会返回大约 10% 的数字(好吧,真的是 10/101)。您可以通过摆弄常量来调整样本。

于 2014-09-16T15:22:10.633 回答
1

有人建议使用 newid() 进行类似的查询,但我正在为您提供适合我的解决方案。

有一种解决方法涉及 newid() 而不是 rand,但它会给您相同的结果。您可以单独执行它,也可以将其作为列中的列执行。它将导致每行的随机值,而不是 select 语句中每一行的相同值。如果您需要 0 - N 的随机数,只需将 100 更改为所需的数字。

SELECT TOP 10 [Flag forca]
,1+ABS(CHECKSUM(NEWID())) % 100 AS RANDOM_NEWID
,RAND() AS  RANDOM_RAND
FROM PAGSEGURO_WORK.dbo.jobSTM248_tmp_leitores_iso

结果

于 2019-02-19T17:20:20.210 回答
0

所以,万一有一天有人会这样做,这就是我最终所做的。

我在服务器端生成随机种子值(在我的例子中是 Java),然后创建一个包含两列的表:id 和生成的 random_id。现在我将视图创建为inner join表和原始数据之间的一个。

生成的 SQL 看起来像这样:

CREATE TABLE SEED_DATA(source_id INT PRIMARY KEY, random_id float NOT NULL);
select Rand(5); 
insert into SEED_DATA values(1,Rand());
insert into SEED_DATA values(2, Rand());
insert into SEED_DATA values(3, Rand());
.
.
.
insert into SEED_DATA values(1000000, Rand());

CREATE VIEW DATA_VIEW
as  
    SELECT row_number() OVER (ORDER BY random_id, id) AS source_id,column1,column2,...
    FROM 
        ( select * from SEED_DATA tmp 
          inner join my_table i on tmp.source_id = i.id) TEMP 

此外,我分批创建随机数,每批 10,000 个左右(可能更高),因此它不会对服务器端造成太大影响,并且对于每个批次,我将其插入到表中以单独执行。

所有这一切都是因为我找不到一种纯粹在 SQL 中做我想做的事的好方法。逐行更新确实效率不高。

我自己从这个故事中得出的结论是,SQL Server 有时真的很烦人......

于 2014-09-29T10:36:39.720 回答
0

您可以从种子中转换一个随机数:

rand(row_number over (order by ___, ___,___))

然后将其转换为 varchar ,然后使用最后 3 个字符作为另一个种子。这会给你一个很好的随机值:

rand(right(cast(rand(row_number() over(x,y,x)) as varchar(15)), 3)
于 2017-07-01T22:55:42.460 回答