postgresql程序,用于获取总值的前10%,20%和30%值

时间:2017-05-09 07:20:24

标签: postgresql stored-procedures

我有一个名为Scoreboard的表,其中包含一个名为score的字段,这是一个包含值27,56,78,12,89,77,34,23,90,87,33,55,30,67,76,87,56的数组,我想写一个PostgreSQL程序来获取三个类别
category 1 = top 10% values of the total no of values in array
category 2 = top 20% values of the total no of values in array
category 3 = top 30% values of the total no of values in array
并以相同的格式将其放入数组中,即 [category 1 values,category 2 values,category 3 values]

2 个答案:

答案 0 :(得分:0)

像这样应该做的事情:

t=# with p as (
  with ntile as (
    with v as (
      select unnest('{27,56,78,12,89,77,34,23,90,87,33,55,30,67,76,87,56}'::int[]) a
    )
    select a,ntile(10) over(order by a desc)
    from v
  )
  select distinct  string_agg(a::text,',') over (partition by ntile),ntile
  from ntile
  where ntile <=3 order by ntile
)
select array_agg(concat('category ',ntile,' ',string_agg))
from p;
                         array_agg
------------------------------------------------------------
 {"category 1 90,89","category 2 87,87","category 3 78,77"}
(1 row)

Time: 0.493 ms

答案 1 :(得分:0)

我假设,你有一个表有一列作为id而另一个是数组类型。基于假设 我已经创建了如下表格,并为其插入了两个值。

create table test_array (id int, values int[]);
insert into test_array values(1 ,'{27,56,78,12,89,77,34,23,90,87,33,55,30,67,76,87,56}' );
insert into test_array values(2 ,'{72,65,84,21,98,77,43,32,9,78,41,66,3,76,67,88,56}' );

以下是用于查找您提及的类别的功能。如果表中没有任何id列 然后你可以使用window function提示添加数字:row_number()。

create or replace function find_category() returns table(category text[]) as 
$$
BEGIN

return query with unnestColumn as (
select id, unnest(values) as values, ntile(10) over(partition by id order by unnest(values) desc) as ntilenumber
from test_array 
) ,groupedCategory as ( select id, ntilenumber, string_agg(values::text,',') as combinedvalues from unnestColumn 
where 
ntilenumber <= 3 
group by id, ntilenumber ) 
select array_agg(concat('Categoty',ntilenumber, ' ', combinedvalues ))
from groupedCategory
group by id;

END;
$$
language 'plpgsql';

执行以下功能检查输出。

select * from find_category();