能否使用AVG函数计算含UNION子查询中两组结果的平均值?嵌套AVG查询合理性咨询
这个问题问得特别好——其实核心在于对平均值再取平均是否能代表真实的整体平均值,关键看你内层每个平均值背后的样本量是否一致,咱们一步步拆解:
你的理解什么时候是对的?
如果对于同一个supplier+year+month分组,两个子查询(tableA关联tableB、tableC关联tableB)的样本数量完全相同,那外层的avg(average)确实能得到正确的整体平均值。
举个例子:假设某个分组里,tableA关联出10条数据,计算出的avg是5;tableC关联出10条数据,avg是6。外层算(5+6)/2=5.5,和直接把20条数据放一起算的整体avg结果是一样的。这种情况下,你把内层平均值当成单一“代表值”来平均的逻辑是成立的。
什么时候会出错?
但如果两个子查询的样本数量不一样,外层的未加权平均就会偏离真实的整体平均值——这也是那位数学专业朋友说“不能对平均值再次取平均”的原因。
比如还是同一个分组:tableA关联出10条数据,avg是5;tableC关联出20条数据,avg是6。外层算出来是(5+6)/2=5.5,但真实的整体avg应该是(10*5 + 20*6)/(10+20)≈5.67。这时候你忽略了样本量的权重,结果自然就不准了。
更稳妥的解决方案
要避免这个问题,最直接的办法是不要提前在子查询里计算平均值,而是把所有原始的age计算结果合并后,再统一计算整体平均值。改写你的SQL如下:
select supplier, year, month, avg(age_diff) as average from ( -- 保留原始的age计算结果,不提前取平均 select supplier, year, month, age(tableA.date, tableB.date) as age_diff from tableA join tableB using(supplier) UNION ALL select supplier, year, month, age(tableC.date, tableB.date) as age_diff from tableC join tableB using(supplier) ) as x group by supplier, year, month
这种方式不管两个子查询的样本量差异多大,最终的平均值都是准确的,因为它直接基于所有原始数据计算。
总结
你的理解在样本量一致的场景下是合理的,但从通用性和准确性角度来说,直接合并原始数据再计算平均值的方案更可靠,也能避免因样本量差异带来的计算偏差。
内容的提问来源于stack exchange,提问作者DChall

