【问题标题】:stratified random sample with counts in postgresql在 postgresql 中具有计数的分层随机样本
【发布时间】:2017-01-18 00:52:30
【问题描述】:

我有一个由calculate_table() 过程生成的下表:

table(
  id integer,
  type integer
)

我希望做一个分层随机样本,在其中我选择一个随机 id,按类型随机化,并返回类型的计数和 id 的计数。

所以在下面的例子中:

id,type
1,1
2,1
3,1
4,1
5,2
6,2
7,2
8,3
9,4

随机化可以选择以下内容:

chosen_type: 2
type_count: 4
chosen_id: 6
id_count: 3

所以会有 25% 的机会获得类型 2,如果选择类型 2,则有 33% 的机会获得 id 6。

以下内容不起作用,因为它是从所有 id 中随机选择的,与它们的类型无关,这不是我想要的。

select * from calculate_table()
order by random()
limit 1;

我在尝试避免多次调用calculate_table() 过程和/或将内容存储在数组中时遇到了麻烦。我该怎么办?

【问题讨论】:

  • 除了存储计算表并多次调用之外,还有什么替代方法?
  • “2”的“type_count”如何为 4?您的查询应该有效。
  • 发布的数据与想要的输出不匹配。
  • @GordonLinoff 因为有 4 种不同的类型可供选择。 id_count 为 3,因为有 3 个类型为 2 的 id 可供选择。

标签: sql postgresql random


【解决方案1】:
with t(id,type) as (values
    (1,1),(2,1),(3,1),(4,1),(5,2),(6,2),(7,2),(8,3),(9,4)
), dt as (
    select type, id
    from t
    group by 1,2
    order by random()
    limit 1
)
select
    type as chosen_type,
    (select count(distinct type) from t) as type_count,
    id as chosen_id,
    (select count(distinct id) from t where type = dt.type) as id_count
from dt;
 chosen_type | type_count | chosen_id | id_count 
-------------+------------+-----------+----------
           2 |          4 |         6 |        3

【讨论】:

    【解决方案2】:

    您可以使用由 random() 排序的窗口函数来实现此目的。

    有关示例,请参阅 this SQLfiddle

    select  *
    from   (
            select  type,
                    row_number() over( order by random() ) as type_random,
                    id, 
                    row_number() over( partition by type order by random() ) as id_random
            from    calculate_table()
           ) as a
     where   type_random = 1
             and id_random = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 1970-01-01
      • 2019-09-20
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      相关资源
      最近更新 更多