如何计算当前值及其以下所有值的总和
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
考虑以下方法
select version, level, count(*) advanced_count
from user_level_advanced,
unnest(generate_array(1, level_advanced_max)) level
group by version, level
如果应用于您问题中的示例数据 - 输出为
我有一个 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
考虑以下方法
select version, level, count(*) advanced_count
from user_level_advanced,
unnest(generate_array(1, level_advanced_max)) level
group by version, level
如果应用于您问题中的示例数据 - 输出为