在 PostgreSQL 中采样
Sampling in PostgreSQL
我正在寻找 PostgreSQL 中随机抽样的可能方法。我找到了几种方法来做到这一点,各有优缺点。天真的方法是:
select * from Table_Name
order by random()
limit 10;
另一种更快的方法是:
select * from Table_Name
WHERE random() <= 0.01
order by random()
limit 10;
(尽管 0.01 取决于 table 大小和样本大小;这只是一个示例。)
在这两个查询中,都会为每一行生成一个随机数,并根据这些随机生成的数进行排序。然后在排序的数字中选择前10个作为最终结果,所以我认为这些应该是无放回抽样。
现在我想做的是以某种方式将这种抽样方法变成有放回抽样。这怎么可能?或者PostgreSQL中有没有其他随机抽样的替换方法?
我不得不说我确实知道这可能是如何实现的,但我不知道如何在 postgresql 中实现它,这是我的想法:
如果不是生成一个随机值而是生成S个随机值,其中S是样本大小,然后对所有随机生成的值进行排序,它将是有放回的采样。(我不知道我是否正确)
此时我不介意查询的性能。
这可以通过将随机值映射到行号来实现。如果恰好对应的同一个随机数出现 N 次,则同一行可以被采样 N 次。这是一个 CTE 实现:
with
rows as (select *,row_number() over() as rn from tablename order by random()),
w(num) as (select (random()*(select count(*) from rows))::int+1
from generate_series(1,10))
select rows.* from rows join w on rows.rn = w.num;
我正在寻找 PostgreSQL 中随机抽样的可能方法。我找到了几种方法来做到这一点,各有优缺点。天真的方法是:
select * from Table_Name
order by random()
limit 10;
另一种更快的方法是:
select * from Table_Name
WHERE random() <= 0.01
order by random()
limit 10;
(尽管 0.01 取决于 table 大小和样本大小;这只是一个示例。)
在这两个查询中,都会为每一行生成一个随机数,并根据这些随机生成的数进行排序。然后在排序的数字中选择前10个作为最终结果,所以我认为这些应该是无放回抽样。
现在我想做的是以某种方式将这种抽样方法变成有放回抽样。这怎么可能?或者PostgreSQL中有没有其他随机抽样的替换方法?
我不得不说我确实知道这可能是如何实现的,但我不知道如何在 postgresql 中实现它,这是我的想法:
如果不是生成一个随机值而是生成S个随机值,其中S是样本大小,然后对所有随机生成的值进行排序,它将是有放回的采样。(我不知道我是否正确)
此时我不介意查询的性能。
这可以通过将随机值映射到行号来实现。如果恰好对应的同一个随机数出现 N 次,则同一行可以被采样 N 次。这是一个 CTE 实现:
with
rows as (select *,row_number() over() as rn from tablename order by random()),
w(num) as (select (random()*(select count(*) from rows))::int+1
from generate_series(1,10))
select rows.* from rows join w on rows.rn = w.num;