SQL 日均值能直接再求平均吗?月均客单价为什么会算错?
面试怎么回答
我会先确认平均的对象。月均客单价按订单加权,应把同口径的金额和订单数分别求和后相除,不能直接平均每日客单价。预聚合层保留分子、分母和缺失标记,零订单与数据缺失分开处理。如果业务确实要看每日客单价的算术平均,就另立指标,明确哪些日期进入分母,并用明细汇总核对。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
第一天只有一笔订单,客单价100元;第二天有九笔订单,客单价20元。两天的平均客单价到底是60元,还是28元?这不是除法题,而是平均对象选错了。
合并平均值要回到同一口径的分子和分母;平均每天的表现与平均每笔订单的表现,不是同一个指标。
先别急着写 AVG,问清谁拥有一票
如果统计的是“随机抽一笔订单,平均支付多少”,每笔订单拥有相同权重。第一天的一笔订单,不能和第二天的九笔订单拥有相同的总权重。
如果统计的是“这两天每日客单价的平均水平”,则每天拥有一票,结果60元也可以成立。问题不在于这个数字绝对错误,而在于把它命名成了全周期订单客单价。
同样的区别会出现在平均响应时间、平均件单价和平均加工耗时中。一个低流量时段,不应在请求级平均耗时里自动获得与高流量时段一样的权重。

聚合层保留分子和分母,比只存均值更重要
假设输入表已经按业务日聚合,并且每笔有效订单仅计一次,金额与订单数来自同一批订单。下面是 PostgreSQL 17 风格的示意查询:
SELECT
SUM(paid_amount)::numeric
/ NULLIF(SUM(valid_order_count), 0) AS avg_order_amount
FROM daily_order_metrics
WHERE biz_date >= DATE '2026-08-01'
AND biz_date < DATE '2026-09-01';
这里没有通过“日均值乘订单数”还原金额,是因为日均值可能已经四舍五入。直接保留原始汇总金额,可以少一次精度损失。
但公式正确还不够。如果金额含退款冲减,订单数却包含被排除的测试单,两边仍然不是同一个总体。指标模型要同时记录订单范围、金额范围、币种和统计时点。
空值不是免费得到的零
在这个数据库里,AVG忽略空值。若部分订单金额未知,AVG金额的分母不等于全部订单行数;用SUM金额除以COUNT全部记录,会悄悄把未知金额当成零贡献。
可以选择只统计金额已知的订单,但指标名和质量提示要说明覆盖范围。也可以先阻断缺失数据的正式发布。不能一边保留全部订单数量,一边把缺失金额静默忽略。
没有订单的日期也要讨论:每日客单价本身没有定义,是否参与“日均客单价”的再平均由业务约定;把它补零,会把没有交易解释成交易均价为零。
一个典型场景:小流量日期改变了整月结论
假设分析师发现月均客单价明显高于按订单明细计算的结果,初步认为明细漏了高价订单。逐日检查后,每天的数据却都能对上。
真正原因是看板对日均值使用AVG,活动高峰有大量低价订单,低流量日期只有少量高价订单。逐日验数没有问题,因为错误只发生在跨日二次汇总时。
修正不是把所有AVG替换成SUM,而是为这个指标提供金额和有效订单数两个基础量,在最终展示粒度计算比值。同时保留按日平均的另一个指标,避免改坏原本需要观察日间波动的报表。
验收时加入订单数极不均衡的样本,再加入零订单日、金额缺失日和退款冲减日,检查不同分母选择是否得到预期结果。
不可合并的结果,不能硬套同一种补救办法
均值能够用总和与数量合并,不代表中位数、分位数、去重人数也能用两个简单数字精确合并。不要把“加权平均”当作所有预聚合指标的通用修复。
金额口径如果换成每个付费用户平均支付金额,还要处理跨日重复用户,不能继续把每日付费人数相加。模型设计时就应声明哪些维度可以汇总、需要保留什么中间信息。
面试里说到这里,重点已经不是背出一个公式,而是证明你能从指标名称反推出统计单位,并让每一层加工保留足够的信息。