加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Sql Server 随机抽样方法

(2009-10-20 22:44:40)
标签:

sql

server

随机抽样

分类: 数据分析
    最近在做对于用户行为的数据分析,由于用户数据记录数据量很大,需要取50000个用户记录作为样本,为了数据分析出来的结果与整体数据偏差较小,我们需要使用抽样的方法从总量用户中随机抽取50000个样本记录。
    现在介绍两种抽样方法:
    1.使用Sql Server中随机函数Rand([Seed])返回0-1之间float随机值,seed为int型种子值可以省略。
      这个函数使用的时候如果省略seed参数rand()则每次都返回一个随机数,如果使用带有seed参数的rand(seed)则每次都返回相同的随机数,只有seed的值发生变化才能改变随机数的值 。
      例如:
          select rand() from test,假如test中有100条数据,则会生成100个随机数.
          select rand(1) from test,则生成100个相同的随机数。
          所以在程序中最好改变种子seed的值:
            declare @count int
            set @count=1
            while @count<5
               select rand(@count) from test
               set @count=@count+1
          这样就会生成5个不同的随机数。
      介绍了这个基本概念,我们现在假设表user保存的是所有用户记录,记录总数为100万,表中有一个userid表示用户的ID唯一值,从这个表中抽取5万的样本,如何来做这件事那.
      首先创建两个临时表,第一个表名为user_total,其中有三列,第一列为自增长ID字段,第二列为用户ID字段,第三列为是否为样本记录列,我们要将100W个用户ID(userid)插入到user_total表中,插入后自增长ID字段也就生成完了,再创建第二个表,名为user_rand,这个表里面只有一列为随机数列,用户使用rand()生成5W个范围为1-100W的随机数,插入到user_rand表中,之后在通过这个随机数查找出user_total第一列自增长ID对应的userid,并把user_total第三列标识为已被抽中。
     这里面可以使用rand()方式,也可以使用上面提到的提供seed循环来生成一组随机数,但是其实这里面有一个问题,select rand() from test 生成的随机数是有可能重复的,谁也没有说随机数就不能重复了,所以5W个随机数中是有重复的,所以这种方法不太可取,使用rand(seed)方式可以提供不同的seed来避免生成重复的随机数,但是有一个问题如果rand(seed)这种方式可能会对随机数产生一定偏移,也不太可取。所以下面介绍另一种方法

2.使用Sql Server NewID()函数:
    NewID()返回一个GUID值(全局唯一标识),这个值不会重复,它根据硬件的标识码和时间进行计算得到的一个全局的唯一字符串,如果能利用它作为随机抽样,将对样本的随机性有很好的提高。
   例如抽去50000个用户ID(userid):
    select top 50000 userid from user_total order by newid()
  这个语句刚一看有点不太明白,首先我们要清楚这条语句是先对user_total所以数据进行排序,按照newid()为每一行生产的GUID值排序,排序之后抽取前50000条记录。






          



          
   

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有