在postgres表中的所有唯一阈值上“区别开”

我有一个名为sample_a的Postgres 11表,如下所示:

 time | cat | val
------+-----+-----
    1 |   1 |   5
    1 |   2 |   4
    2 |   1 |   6
    3 |   1 |   9
    4 |   3 |   2

我想创建一个查询,该查询针对每个唯一的时间步,获取该时间步或该时间步之前每个类别的最新值,并通过取这些值的总和除以这些值的计数来汇总这些值。

我相信我有查询要在给定的时间范围内执行此操作。例如,对于时间3,我可以运行以下查询:

select sum(val)::numeric / count(val) as result from (
    select distinct on (cat) * from sample_a where time <= 3  order by cat,time desc
) x;

并获得6.5。 (这是因为在时间3上,类别1中的最新值为9,类别2中的最新值为4。值的计数为2,它们总计为13,而13 / 26.5。)

但是,理想情况下,我希望运行一个查询,该查询将为我提供表中每个唯一时间的所有结果。此新查询的输出如下所示:

 time | result
------+----------
    1 |   4.5
    2 |   5
    3 |   6.5
    4 |   5

理想情况下,这个新查询将避免添加另一个subselect子句;一个高效的查询将是首选。我可以通过在每个时间步长在应用程序中运行先前的查询来获得这些先前的结果,但是对于大的sample_a来说,这似乎并不高效。

这个新查询是什么样子?

zhangwei805 回答:在postgres表中的所有唯一阈值上“区别开”

以这种方式查看性能是否可以接受。语法可能需要稍作调整:

select t.time,avg(mr.val) as result
from (select distinct time from sample_a) t,lateral (
        select distinct on (cat) val
        from sample_a a
        where a.time <= t.time
        order by a.cat,a.time desc
    ) mr
group by t.time
,

我认为您只需要累积函数:

select time,sum(sum(val)) over (order by time) / sum(sum(num_val)) over (order by time) as result
from (select time,sum(val) as sum_val,count(*) as num_val
      from sample_a a
      group by time
     ) a;

请注意,如果val是整数,则可能需要转换为数字以获取小数值。

这也可以不用子查询来表达:

select time,sum(sum(val)) over (order by time) / sum(count(*)) over (order by time) as result
from sample_a
group by time
本文链接:https://www.f2er.com/3147149.html

大家都在问