如何计算当前值及其以下所有值的总和

How to calculate sum for current value and all the values below it

我有一个 table,其中包含有关特定版本的每个用户级别的信息。假设它的名字是 user_level_advanced.

version user_id level
0.9.3 1 2
0.9.5 2 3
0.9.3 3 4
0.9.3 4 5

并且我想计算每个级别提升了多少次,以便每个用户都应该被视为低于其当前级别的级别。对于上面的table,结果应该是这样的。

version level advanced_count
0.9.3 1 3
0.9.3 2 3
0.9.3 3 2
0.9.3 4 2
0.9.3 5 1
0.9.5 1 1
0.9.5 2 1
0.9.5 3 1
with user_level_advanced as(
    select 
        "0.9.3" as version, 1 as user_id, 2 as level_advanced_max
        union all
       select  "0.9.5" as version, 2 as user_id, 3 as level_advanced_max
        union all 
        select "0.9.3" as version, 3 as user_id, 4 as level_advanced_max
        union all 
        select "0.9.3" as version, 4 as user_id, 5 as level_advanced_max
),
user_grouped_by as
(
    select version, level_advanced_max, count(*) as level_advanced_count 
    from user_level_advanced 
    group by version, level_advanced_max
)

select  version,
        level_advanced_max,
        sum(level_advanced_count) over(partition by version order by level_advanced_max asc rows between current row and unbounded following)
from user_grouped_by

我使用这个查询来计算它,但它有一个缺陷,如果 user_level_advanced table 中缺少一个级别,结果 table 也会丢失.感谢您的帮助。

version level advanced_count
0.9.3 2 3
0.9.3 4 2
0.9.3 5 1
0.9.5 3 1

您可以使用 cross join 生成所有可能的(级别、版本)对,然后将其加入您的 table 以获得预期结果:

with recursive levels as
(select 1 as level
union all
select level + 1 from levels
where level < (select max(level) from user_level_advanced)),
versions as
(select distinct version from user_level_advanced),
cte as
(select * from versions cross join levels)
select cte.version, cte.level, count(*)
from cte inner join user_level_advanced ula
on ula.level >= cte.level and ula.version = cte.version
group by cte.version, cte.level

Fiddle

考虑以下方法

select version, level, count(*) advanced_count
from user_level_advanced, 
unnest(generate_array(1, level_advanced_max)) level
group by version, level         

如果应用于您问题中的示例数据 - 输出为