SQL Sever 中随机抽样,分层抽样和平衡抽样

3.3 对表做抽样

3.3.1 随机抽样

--获取10%的随机样本数据
SELECT t.*
FROM <t> t
WHERE RAND() < 0.1

但是不能用在SQL Sever中,要用 NEWID(),可是有个问题是这样必须为表汇总的所有记录排序,
过于耗费资源,解决办法是使用NEWID()

SELECT TOP PERCENT t.*
FROM <T> t
ORDER BY NEWID()
返回数据的10%

SELECT t.*
FROM <t> t
WHERE RAND(CHECKSUM(NEWID())) < 0.1
这个查询为随机数生成器提供种子,每次调用时的种子都不同,以满足每次调用时对不同值的需求。

3.3.2 可重复的随机样本
使用ID作为随机数生成器的种子:

SELECT t.*
FROM <t> t
WHERE RAND(id) < 0.1

每次输入某个ID时,都会生成同样的随机数,为了获取不同的样本,可以修改种子:
WHERE RAND(id + 1) < 0.1
另一个方法是基于 ROW_NUMBER()的伪随机数生成器。
WITH t as (
			 SELECT t.*, ROW_NUMBER() OVER (ORDER BY col) as seqnum
			 FROM <t> t
	)
SELECT t.*
FROM t
WHERE (t * 17 + 57) % 101 <= 10;

3.3.3 分层比例抽样
分层抽样能够保证列值的分布和整体分布相近,subscribers表有47.18%的活跃的订阅者。
WITH a as (
				SELECT s.*, ROW_NUMBER() OVER (ORDER BY isactive) as seqnum
				FROM subscribers s
					)
SELECT AVG(1.0 * isactive)
FROM a
WHERE seqnum % 100 = 1;

CTE依次为非活跃者和活跃者分配连续的数字,然后每隔99个数据抽取第100个数据,这个程序从每100个
非活跃者中抽取一条数据,从100个活跃者中抽取一条数据。返回值47.18,与原始数据相同

分层抽样的优势在于可以应用于不止一个变量,下面例子,包含以市场和活跃度划分的与原始数据相同比例的样本

WITH s as (
		SELECT s.*, ROW_NUMBER() OVER (ORDER BY market, isactive) as sequm
		FROM subscribers s
)
SELECT AVG(isactive)
FROM s
WHERE sequm % 100 = 1;

3.3.4 平衡的样本

WITH o as (
			SELECT o.*,
			ROW_NUMBER() OVER (PARTITION BY isae ORDER BY NEWID()) as seqnum
			FROM (SELECT o.*,
									 (CASE WHEN paymenttype = 'AE' THEN 1 ELSE 0 END) as isae
						FROM orders o
						WHERE totalprice <= 200
					) o
			)
SELECT orderdate,
			(CASE WHEN isae = 1 THEN totalprice END) as ae,
			(CASE WHEN isae = 0 THEN totalprice END) as notae
FROM o
WHERE seqnum <= 100;

 

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值