Sql postgres中同时计算平均值和标准差的有效方法

Sql postgres中同时计算平均值和标准差的有效方法,sql,postgresql,Sql,Postgresql,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_lengt

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()计算一次并重用它:


根据评论,我将执行时间缓慢归因于多个平均聚合,而实际上这是由于不必要的联接。

要将两个表合并到一个结果中,必须在联接之前进行聚合:

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 ;

stddev_pop()
不需要计算中间平均值。有许多方法可以实现相同的计算。您的查询正在进行11645x14380=167455100行的交叉连接。除了生成1.67亿行、存储在内存和/或磁盘上、扫描整个结果集并计算平均值之外,没有其他算法可以计算这些数字吗?生成这个交叉连接,然后扫描它是最昂贵的操作,平均两次只需要最小的开销。你说得对@krokodilko,我在一个单独的查询中计算了每个表的统计数据,几乎是即时的。这两个表在原始查询中连接的原因很明显吗?似乎是不必要的步骤。为什么要在两个表之间创建交叉连接?你不应该用一个
JOIN
来代替吗?但只要没有WHERE子句,Seq Scan将是唯一明智的选择,因为您需要两个表中的所有行。我没有意识到查询将以这种方式执行,没有理由我不能简单地分别执行查询,然后合并结果。