繁体   English   中英

Postgresql:如何根据项目对总计的百分比进行分组

[英]Postgresql: How to group items based on their percentage to the grandtotal

    store_id   product_name   quantity
       1          apple          10
       1          orange         12
       1          grapes          9
       1          mango          17
       2          chicken        112
       2          beef           90
       2          pork           89
       2          lamb           115

我想根据他们按store_id分组的总和的百分比,从顶部和底部50%对它们进行分组,并将底部产品标记为“其他”,如下所示:

     store_id    product_name    percent
        1           mango         35.42%
        1           orange        25.00%
        1           OTHER         20.83%
        1           OTHER         18.75%
        2           lamb          28.33%
        2           chicken       27.59%
        2           OTHER         22.17%
        2           OTHER         21.92%

这可能吗? 我真的很难用谷歌搜索这个,这就是为什么我来这里的原因。 谢谢!

假设表名为gt,则:

t=# with a as (select *,round( quantity * 100.0 / sum(quantity) over(partition by store_id), 2) r from gt)
,b as (select *, sum(r) over (partition by store_id order by r desc) from a)
select store_id, case when coalesce(lag(sum) over (partition by store_id) < 50 ,true) then product_name else 'OTHER' end product_name, r||'%' percent from b;
 store_id | product_name | percent
----------+--------------+---------
        1 | mango        | 35.42%
        1 | orange       | 25.00%
        1 | OTHER        | 20.83%
        1 | OTHER        | 18.75%
        2 | lamb         | 28.33%
        2 | chicken      | 27.59%
        2 | OTHER        | 22.17%
        2 | OTHER        | 21.92%
(8 rows)

假设使用以下代码创建数据:

create table product(
  store int, 
  name text,
  qtd int
  );


insert into product values(1,' apple',10);
insert into product values(1,' orange',12);
insert into product values(1,' grapes',9);
insert into product values(1,' mango',17);
insert into product values(2,' chicken',112);
insert into product values(2,' beef',90 );
insert into product values(2,' pork',89 );
insert into product values(2,' lamb',115);

您可以通过以下查询获取所需的输出:

with total_query as (
  SELECT store, sum(qtd) AS totalamount 
    FROM product 
    GROUP BY store 
  ),
count_query as (
  SELECT store, count(qtd) AS totalcnt 
    FROM product 
    GROUP BY store 

  ),
percent_query as (

select p.store, p.name, 
  round(p.qtd::float/(select totalamount from total_query
          where total_query.store = p.store)*100) as percent

  from product p

)

select store, 
case when row_number() over (
  partition by store order by percent desc)/
(select totalcnt from count_query where store = p.store)::float <= 0.5 
then 'Other' else name end, percent 

from percent_query p order by store, percent

| store |    name | percent |
|-------|---------|---------|
|     1 |  grapes |      19 |
|     1 |   apple |      21 |
|     1 |   Other |      25 |
|     1 |   Other |      35 |
|     2 |    beef |      22 |
|     2 |    pork |      22 |
|     2 |   Other |      28 |
|     2 |   Other |      28 |

我可以这样写:

select t.*,
       quantity / sum(quantity) over (partition by store_id) as ratio,
       (case when sum(quantity) over (partition by store_id order by quantity desc) - quantity <
                  0.5 * sum(quantity over (partition by store_id) as running_ratio
             then product_name
             else 'Other'
        end) as product_name
from t;

请注意,这会产生一个单独的行对每个Other ,如在你的榜样。 在实践中,我想将它们结合起来。 如果您想要这样做(但不知道该怎么做),请问另一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM