预算按月、实际按天,数仓里怎么对比才不会把预算算重?
面试怎么回答
我会先声明预算和实际的粒度,包含月份、组织、币种和预算版本。比较时两侧分别聚合到共同粒度后再关联,不让月预算直接随每日事实重复。需要日级或渠道级预算,就使用经过确认的分摊规则并保证上卷守恒;没有分摊依据时只展示上级预算或标识不适用。完成率由同口径实际除以预算,不能简单平均明细完成率。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
月预算100万元,关联30天实际数据后,报表里的预算变成3000万元。把预算改成 MAX,月总计暂时对了;一按部门、渠道切换,又开始不对。这类问题不是换个聚合函数就能收尾,而是预算与实际的粒度没有对齐。
不同粒度事实先各自汇总到可比较粒度;预算下钻必须有分摊规则,不能由关联重复代替。
预算表不是一张特殊的订单明细
预算可能按月、部门、费用科目、币种和版本记录;实际发生可能按天、项目、渠道甚至单据行记录。
两边共有部门名称,不代表已经可以直接关联。还要核对部门历史映射、科目范围、税费口径和币种,否则金额即使没重复,也可能是在比较两件不同的事。
预算版本尤其容易漏掉。年初版、调整版、最新预测版并不是可以相加的三份预算。先确定报表选用哪个版本,才谈后续对比。
先汇总到双方都能表达的粒度
如果预算只到“月—部门—科目”,最稳妥的月度比较是让实际也汇总到这个粒度,再与对应预算版本关联。
两侧分别聚合,可以减少事实之间的一对多扩张。关联键需要覆盖完整共同粒度,而不是只用月份和部门,漏掉币种后仍可能成倍匹配。
只有预算、没有实际的组合,也应按报表目的保留;只有实际、没有预算的超范围发生,不能因为内关联被悄悄删除。未编预算与预算为零,要有不同标识。

日级完成率必须解释分母
业务想看“今天预算完成率”,至少有三种合理含义:本月累计实际除以全月预算、累计实际除以截至今天的计划预算、当天实际除以当天分摊预算。
第一种不需要人为造出日预算,但它回答的是月目标累计进度。第二种和第三种需要日计划或分摊曲线,不能只靠 SQL 生成一个看起来顺滑的数字。
平均分摊不是默认真相。工作日、节假日、活动日的计划节奏可能不同;使用历史权重还要明确参考期间、异常处理和规则版本。尾差如何归集也需要可复核。
一个典型场景:MAX 只是碰巧救了一个格子
比如月预算100万元被重复到30天,SUM 得到3000万元。最初直接改为 MAX,月总计恢复为100万元,验收因此通过。
后来一张报表同时选择两个独立部门,每个部门预算100万元,MAX 仍然只返回100万元。根因是聚合函数被当成了粒度修复工具,它不知道哪几行是重复展示、哪几行是不同预算。
修复要回到预算事实的唯一键,并在共同粒度单独汇总。旧检查只覆盖一个月、一个部门,无法验证跨部门上卷;新增样本应覆盖多月、多部门、多版本及缺预算组合。
如果展示层必须在每日行重复显示月预算,应把它当作非可加总展示项,同时规定总计计算方式;不能把重复列再暴露给任意 SUM。
分摊是一份业务结果,不只是数学技巧
如果决定把月预算拆到渠道和日期,应该产生可追溯的分摊明细,包含原预算键、目标粒度、权重、分摊金额和规则版本。
先检查同一预算下有效权重之和是否为一,再检查金额上卷是否回到原预算。权重缺失不应直接默认为零,尤其不能让一部分预算凭空消失。
组织调整时,还要区分按当时组织比较与按当前组织重述。预算与实际若一边用旧组织、一边用新组织,偏差可能来自映射,而非经营表现。
最后,跨部门完成率应该用实际总额除以预算总额,不能简单平均部门百分比。预算为零时,完成率如何显示也由业务约定,别用一个极大数字制造假的可比性。
这道题背后真正的能力,是在业务想下钻时解释数据能支持到哪一层,而不是让每一行都硬塞一个预算。