从Postgresql中的视图中选择随机样本

从Postgresql中的视图中选择随机样本,sql,postgresql,Sql,Postgresql,我从PostgreSQL中的一个表生成了一个视图,该表由50000行组成。我想根据一些条件从这个视图中随机抽取一个样本。我理解这可以通过以下方式实现: select * from viewname where columnname = 'A' -- the condition order by columnname limit 5; 但是,我想取满足此条件的行数的百分比,而不是“限制5”。例如,“限制5%”(虽然这不是正确的语法)。我知道可以用tablesample子句做类似的事情,但这不

我从PostgreSQL中的一个表生成了一个视图,该表由50000行组成。我想根据一些条件从这个视图中随机抽取一个样本。我理解这可以通过以下方式实现:

select * from viewname
where columnname = 'A'  -- the condition
order by columnname 
limit 5;

但是,我想取满足此条件的行数的百分比,而不是“限制5”。例如,“限制5%”(虽然这不是正确的语法)。我知道可以用tablesample子句做类似的事情,但这不适用于视图

您可以使用窗口函数PERCENT\u RANK

SELECT *
FROM 
(
  select *, PERCENT_RANK() OVER (PARTITION BY columnname ORDER BY random()) AS pcrnk
  from tablename
  where columnname = 'A'
) q
WHERE pcrnk <= 0.05

您可以使用窗口函数PERCENT\u RANK

SELECT *
FROM 
(
  select *, PERCENT_RANK() OVER (PARTITION BY columnname ORDER BY random()) AS pcrnk
  from tablename
  where columnname = 'A'
) q
WHERE pcrnk <= 0.05

为了随机选择行的百分比,如果您有Postgres 9.5或更高,请查看Postgres

它有两个选项:
BERNOULLI
SYSTEM

贝努利和系统抽样方法都接受一个参数,该参数是要抽样的表的分数,表示为0到100之间的百分比。[…]这两个方法各自返回一个随机选择的表样本,该样本将包含大约指定百分比的表行

SYSTEM
速度更快,但
BERNOULLI
提供了更好的随机分布,因为每个记录被选中的概率相同

SELECT * 
FROM tablename TABLESAMPLE SYSTEM(5)
WHERE columnname = 'A'  -- the condition
ORDER BY columnname;

注意:这仅在查询表时有效,而不是查询视图。

为了随机选择一定百分比的行,如果您有Postgres 9.5或更高版本,请查看Postgres

它有两个选项:
BERNOULLI
SYSTEM

贝努利和系统抽样方法都接受一个参数,该参数是要抽样的表的分数,表示为0到100之间的百分比。[…]这两种方法各自返回随机选择的表示例,该样本将包含表行的指定百分比

SYSTEM
速度更快,但
BERNOULLI
提供了更好的随机分布,因为每个记录被选中的概率相同

SELECT * 
FROM tablename TABLESAMPLE SYSTEM(5)
WHERE columnname = 'A'  -- the condition
ORDER BY columnname;


注意:这仅在查询表时有效,不支持视图。

采样的标准方式是
orderbyrandom()
采样的标准方式是
orderbyrandom()
是,但不支持视图。@LaurenzAlbe:ah,好的,我明白了。。。谢谢检查,我正在删除我的答案,因为它没有正确地回答问题。不要删除它。这仍然是一个有价值的答案。只需补充一句话。起初,这个问题没有使用viewname,而是使用tablename。TABLESAMPLE的文档说“此采样先于任何其他筛选器(如WHERE子句)的应用。”因此,在上面给出的示例中,5%的行被筛选为“columnname=‘A’”。这是一种罕见的情况,你可能最终只有很少甚至没有记录。是的,但这不支持视图。@LaurenzAlbe:啊,好的,我明白了。。。谢谢检查,我正在删除我的答案,因为它没有正确地回答问题。不要删除它。这仍然是一个有价值的答案。只需补充一句话。起初,这个问题没有使用viewname,而是使用tablename。TABLESAMPLE的文档说“此采样先于任何其他筛选器(如WHERE子句)的应用。”因此,在上面给出的示例中,5%的行被筛选为“columnname=‘A’”。这是一种罕见的情况,你可能会有很少甚至没有记录。这似乎工作得很好,非常感谢!最后一件事——我的目标是获取满足不同条件的行的百分比,例如
其中columnname='B'
,等等。有没有更惯用的方法来实现这一点,或者我每次都必须创建不同的select语句?@EarlofMar不知道你的意思。比如columnname等于“A”或“B”?然后只需将WHERE子句更改为
WHERE columnname in('A','B')
。然后,由于columnname上的分区,您得到5%的“A”加上5%的“B”。如果你想要全部的5%,只需移除分区。抱歉,应该更清楚。所以我想取不同百分比的‘A’、‘B’等等,我想知道我是否可以在每次都不写select语句的情况下做到这一点。例如,我首先要取'A'的5%,然后取'B'的10%,依此类推。@EarlofMar嗯,在外部查询q的WHERE子句中,这似乎很容易做到<代码>哪里((columnname='A'和pcrnk@EarlofMar Test Dfiddle这似乎工作得很好,非常感谢!最后一件事-我的目标是获取满足不同条件的行的百分比,例如
其中columnname='B'
,等等。是否有更惯用的方法来实现这一点,或者我每次都必须创建不同的select语句?@EarlofMar不确定您的意思。类似columnname等于'A'或'B'?然后只需将WHERE子句更改为
WHERE columnname in('A','B')
。然后,由于columnname上的分区,您可以得到5%的“A”加上5%的“B”。如果您想要所有分区的5%,请删除该分区。抱歉,应该更清楚。因此,我想取不同百分比的“A”、“B”等,并想知道是否可以在每次不写出select语句的情况下执行此操作。例如,我首先要取5%的“A”,然后取10%的“B”,依此类推。@EarlofMar嗯,在外部查询q的WHERE子句中,这似乎很容易做到。
WHERE((columnname='A'和pcrnk@EarlofMar Test dbfiddle