[英]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.