1

我有一个包含利润和交易数量列的用户表:

在此处输入图像描述
...

我想平均三组用户的利润 - 交易数量相对较多,交易数量平均,交易数量少。

要获得范围系列,我使用 generate_series:

SELECT generate_series(
    max(transactions_year)/3,
    max(transactions_year),
    max(transactions_year)/3
)
FROM portfolios_static 

我确实得到了三类:

在此处输入图像描述

我需要一张这样的桌子:

在此处输入图像描述

如何获得属于每个类别的用户的平均利润并计算属于每个类别的用户数?

4

2 回答 2

1

这将做:

with s as
(SELECT max(transactions_year)/3 series FROM portfolios_static
 UNION ALL 
 SELECT max(transactions_year)/3 * 2 series FROM portfolios_static
 UNION ALL 
 SELECT max(transactions_year) series FROM portfolios_static
),
s1 as
(SELECT generate_series(
    max(transactions_year)/3,
    max(transactions_year),
    max(transactions_year)/3
) AS series
FROM portfolios_static
),
srn as
(SELECT series,
row_number() over (order by series) rn
from s),
prepost as
(select coalesce(pre.series,0) as pre,
 post.series as post
 from srn post
 left join srn pre on pre.rn = post.rn-1)
select pp.post number_of_deals_or_less,
avg(profit_perc_year) average_profit,
count(*) number_of_users 
from portfolios_static p INNER JOIN prepost pp 
ON p.transactions_year > pp.pre AND p.transactions_year <= pp.post
GROUP by pp.post
order by pp.post;

顺便说一句,我不得不放弃 generate_series 并只使用普通的 UNION ALL,因为当最大值不能被 3 整除时,生成系列不会返回正确的 MAX() 值。例如,如果将srnCTE 替换为

srn as
(SELECT series,
row_number() over (order by series) rn
from s1), -- use generate_series

您会注意到,在某些情况下,系列中的最后一个值会小于max(transactions_year)

SQL小提琴

于 2014-02-27T22:15:03.240 回答
1

这可以更简单、更快。假设没有条目有 0 个交易:

SELECT y.max_deals AS deals
     , avg(profit_perc_year) AS avg_profit
     , count(*) AS users
FROM  (
   SELECT (generate_series (0,2) * x.max_t)/3 AS min_deals
         ,(generate_series (1,3) * x.max_t)/3 AS max_deals
   FROM   (SELECT max(transactions_year) AS max_t FROM portfolios_static) x
   ) y
JOIN   portfolios_static p ON p.transactions_year >  min_deals
                          AND p.transactions_year <= max_deals
GROUP  BY 1
ORDER  BY 1;

SQL小提琴。

于 2014-02-27T22:29:27.177 回答