首页 > 解决方案 > 在 postgres 中同时计算 AVG 和 stddev_pop 的有效方法

问题描述

stddev_pop() 必须计算 AVG() 作为标准偏差完整计算的一部分(除非有我不知道的快捷方式)。

对于上下文,目标是测试这两个 geom 列之间的均值差异。

有什么方法可以访问它以避免重新计算 AVG()?

这是一个示例查询:

select 
    avg(st_length(cons.geom)) as source_avg_length,
    avg(st_length(csn.geom)) as target_avg_length,
    stddev_pop(st_length(cons.geom)) as source_std_length,
    stddev_pop(st_length(csn.geom)) as target_std_length
from 
    received.conflation_osm_no_service cons,
    received.conflation_stress_network csn ;

它的输出EXPLAIN ANALYZE让我觉得如果我要求 avg() 和 stddev_pop() 它只会执行一次 avg() 计算并重用它?:

解释分析

标签: sqlpostgresql

解决方案


要将两个表组合成一个结果,您必须在加入之前聚合:

select *
from 
 (  
   select 
       avg(st_length(geom)) as source_avg_length,
       stddev_pop(st_length(geom)) as source_std_length
   from received.conflation_osm_no_service cons
 ) as src
cross join
 (
   select 
       avg(st_length(geom)) as target_avg_length,
       stddev_pop(st_length(geom)) as target_std_length,
   from 
       received.conflation_stress_network csn ;
 ) as tgt

或每张表获得一行:

select 'source' as tablename,
    avg(st_length(geom)) as avg_length,
    stddev_pop(st_length(geom)) as std_length
from 
    received.conflation_osm_no_service cons

union all

select 'target',
    avg(st_length(geom)),
    stddev_pop(st_length(geom)),
from 
    received.conflation_stress_network csn ;

推荐阅读