SQL Server:如何将数据库记录划分为均匀的随机组

时间:2017-09-18 20:58:48

标签: sql-server random

tblNames

  • OrganizationID(int)
  • LastName(varchar)
  • ...
  • GroupNumber(int)
对于所有记录,

GroupNumber当前为NULL,我需要UPDATE语句来更新此列。

我需要将OrganizationID级别的记录拆分为均匀的随机组。

如果有< OrganizationID的20,000条记录,我需要2个偶数随机组。因此,OrganizationID的记录的GroupNumber为1或2. GroupNumber = 1GroupNumber = 2的记录数相同(或者只有1的奇数记录差异) OrganizationID,并且没有可识别的方法来告诉一个人如何进入GroupNumber - 即以AL开头的LastNames是第1组,MZ是第2组不会。

如果有> OrganizationID的20,000条记录,我需要4个随机组。因此,GroupNumber的记录的GroupNumber值为1,2,3或4.每个记录的记录数相同(或者如果奇数记录的差异仅为1) organizationID,并且没有可识别的方法来告诉一个人如何进入GroupNumber - 即以AF开头的LastNames是第1组,GL是第2组,等等不会。

只有大约20个组织,因此我可以运行20次更新语句,如果需要,每var AWS = require('aws-sdk'); exports.sendAWSMail = function(message, destination){ const ses = new AWS.SES(); var data = { Destination: { ToAddresses: [ "blahblah@gmail.com" ] }, Message: { Body: { Html: { Charset: "UTF-8", Data: "This message body contains HTML formatting. It can, for example, contain links like this one: <a class=\"ulink\" href=\"http://docs.aws.amazon.com/ses/latest/DeveloperGuide\" target=\"_blank\">Amazon SES Developer Guide</a>." }, Text: { Charset: "UTF-8", Data: "This is the message body in text format." } }, Subject: { Charset: "UTF-8", Data: "Test email" } }, Source: "no-reply@frutacor.com.br", } ses.sendEmail(data, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response }); } 一次。

我可以完全控制表格,所以我可以添加键或列,但现在就是这样。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

随机创建行号(使用ROW_NUMBERGETID)。然后根据记录计数得到他们的模2或4,以获得0到1或0到3的桶。

select 
  organizationid, lastname, ...,
  case when cnt <= 20000 then rn % 2 else rn % 4 end as bucket
from
(
  select 
    organizationid, lastname, ...,
    row_number() over(order by newid()) as rn,
    count(*) over () as cnt
  from mytable
) randomized;

更新:我认为更新语句必须如下所示:

with randomized as
(
  select 
    groupnumber,
    row_number() over(order by newid()) as rn,
    count(*) over () as cnt
  from mytable
)
update randomzized
set groupnumber = case when cnt <= 20000 then rn % 2 else rn % 4 end + 1;

答案 1 :(得分:1)

另一种稍微不同的方法;

设置一些虚假数据:

hg help revsets

然后使用很少有用的if object_id('tempdb.dbo.#Orgs') is not null drop table #Orgs create table #Orgs ( RID int identity(1,1) primary key clustered, OrganizationId int, LastName varchar(36), GroupId int ) insert into #Orgs (OrganizationId, LastName) select top 40000 row_number() over (order by (select null)) % 20000, newid() from sys.all_objects a, sys.all_objects b 函数来尽可能接近相同大小的组。按ntile()排序基本上是随机排序数据(或随机生成一个guid到下一个)。

newid()

然后,您可以根据组织数量将declare @NumRandomGroups int = 4 update o set GroupId = x.GroupId from #orgs o inner join (select RID, GroupId = ntile(@NumRandomGroups) over (order by newid()) from #orgs) x on o.RID = x.RID select GroupId, count(1) from #Orgs group by GroupId select * from #Orgs order by RID 设置为您想要的任何内容