我在 Postgres 数据库中有未堆叠的数据,试图跨列执行计算。
这是我的数据:
组 | obs1 | obs2 | obs3 | obs4 | obs5 |
---|---|---|---|---|---|
1 | 74.030 | 74.002 | 74.019 | 73.992 | 74.008 |
2 | 73.995 | 73.992 | 74.001 | 74.011 | 74.004 |
3 | 73.988 | 74.024 | 74.021 | 74.005 | 74.002 |
4 | 74.002 | 73.996 | 73.993 | 74.015 | 74.009 |
尝试获取各列的平均值和范围 (Max()-Min())。 以下是期望的结果:
| group | obs1 | obs2 | obs3 | obs4 | obs5|grp_avg| grp_range|
|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:------:|
|1 |74.030 | 74.002| 74.019| 73.992| 74.008| 74.010| 0.038 |
|2 |73.995 | 73.992| 74.001| 74.011| 74.004| 74.001| 0.019 |
|3 |73.988 | 74.024| 74.021| 74.005| 74.002| 74.008| 0.036 |
|4 |74.002 | 73.996| 73.993| 74.015| 74.009| 74.003| 0.022 |
我看着this问题,不明白,但不相信它解决了这个问题。基于那个问题,它指向 Postgres documentation 但它似乎比我想要做的要复杂得多。
在
Pandas DataFrame
(我现在是怎么做的)中,可以选择更改axis
参数,使函数在列而不是行上工作。我希望 Postgres 具有某种类似的功能。
基本上,引用的公认解决方案回答了您的问题。为了更好地理解它,它可以用 common table expression 来表示。 这样做的好处是查询是逐步创建的,您可以在每个阶段检查结果(参见 db<>fiddle)。
with one_column as (
select
grp,
unnest(array[obs1, obs2, obs3, obs4, obs5]) as elem
from my_table
),
aggs as (
select
grp,
avg(elem)::numeric(20, 3),
max(elem)- min(elem) as rng
from one_column
group by grp
)
select
grp,
obs1, obs2, obs3, obs4, obs5,
avg,
rng
from aggs
join my_table using(grp)
order by grp;
或者,您可以使用函数 greatest() 和 least() 来计算聚合。
select
grp, obs1, obs2, obs3, obs4, obs5,
((obs1+ obs2+ obs3+ obs4+ obs5)/ 5)::numeric(20, 3) as avg,
greatest(obs1, obs2, obs3, obs4, obs5)- least(obs1, obs2, obs3, obs4, obs5) as rng
from my_table;