dpi*_*wal 5 sql database postgresql postgresql-9.1
我们是postgres的新手,我们有以下查询,我们可以从中选择每个类别的前N个记录.
create table temp (
gp char,
val int
);
insert into temp values ('A',10);
insert into temp values ('A',8);
insert into temp values ('A',6);
insert into temp values ('A',4);
insert into temp values ('B',3);
insert into temp values ('B',2);
insert into temp values ('B',1);
select a.gp,a.val
from temp a
where a.val in (
select b.val
from temp b
where a.gp=b.gp
order by b.val desc
limit 2);
Run Code Online (Sandbox Code Playgroud)
上述查询的输出是这样的
gp val
----------
A 10
A 8
B 3
B 2
Run Code Online (Sandbox Code Playgroud)
但是我们的要求是不同的,我们希望从n类未固定的每个类别中选择前n%记录,n基于每个组中元素的百分比.
a_h*_*ame 16
要根据每个组中行数的百分比检索行,可以使用两个窗口函数:一个用于计算行,另一个用于为它们提供唯一编号.
select gp,
val
from (
select gp,
val,
count(*) over (partition by gp) as cnt,
row_number() over (partition by gp order by val desc) as rn
from temp
) t
where rn / cnt <= 0.75;
Run Code Online (Sandbox Code Playgroud)
SQLFiddle示例:http://sqlfiddle.com/#!15/94fdd/1
顺便说一句:使用char几乎总是一个坏主意,因为它是一个固定长度的数据类型,填充到定义的长度.我希望你只是为了设置这个例子而做的,不要在你的真实表中使用它.
xrp*_*pza 11
引用a_horse_with_no_name的响应,您可以使用percent_rank()实现类似的效果
SELECT
gp,
val,
pct_rank
FROM (
SELECT
gp,
val,
percent_rank() over (order by val desc) as pct_rank
FROM variables.temp
) t
WHERE pct_rank <= 0.75;
Run Code Online (Sandbox Code Playgroud)
然后,您可以设置最终的 WHERE 子句以按您需要的任何percent_rank()阈值返回数据。