Spark中ROW_NUMBER() OVER(ORDER BY RAND())能否生成随机行号并抽样本?
关于Spark随机样本抽取的SQL问题解答
1. 第一个SQL是否能生成随机行号?
是的,这段SQL可以为视图中的每一行生成随机行号:
WITH t1 AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY RAND()) as rn FROM my_temp_view )
RAND()函数会为每一行生成一个0到1之间的随机浮点数,ROW_NUMBER()基于这个随机数排序后分配行号,相当于给所有行做了随机排序并编号。如果需要可重复的随机结果(比如调试场景),可以给RAND()传入固定种子,比如RAND(123),这样每次执行生成的随机序列完全一致。
2. 抽取1000行随机样本的语句是否合理?
你的语句能得到预期结果,但存在冗余操作:
SELECT * FROM t1 ORDER BY rn LIMIT 1000
因为t1中的rn已经是随机排序后的行号,不需要再次执行ORDER BY rn,直接用WHERE rn <= 1000就能获取前1000个随机行,执行效率更高:
SELECT * FROM t1 WHERE rn <= 1000
更高效的随机样本抽取方式
Spark SQL提供了更直接的方法获取随机样本,无需生成行号:
- 按固定行数抽取:
SELECT * FROM my_temp_view TABLESAMPLE(1000 ROWS)
- 按比例抽取(需根据总数据量估算比例,比如抽取0.1%的样本):
SELECT * FROM my_temp_view TABLESAMPLE(0.1 PERCENT)
- 用
RAND()精准过滤(适合需要严格控制随机性的场景):
SELECT * FROM my_temp_view WHERE RAND() < (1000.0 / (SELECT COUNT(*) FROM my_temp_view))
这种方式需要先计算总数据量,确保抽取的样本数量接近1000行。
内容的提问来源于stack exchange,提问作者Jas
相关产品推荐
相关产品推荐

