7.0 KiB
7.0 KiB
15 · 技术参考:指标口径一致性分析
从数据溯源审计中提取的跨页面重复指标口径对比,以及已发现和待修复的问题清单。
1. 跨页面核心指标口径对比
1.1 营业收入(消费金额)
| 页面 | 前端变量 | API | API字段 | 数据源表.字段 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.consumption |
/overview | consumption |
analytics.bill_fact.consumption |
| 老板驾驶舱 | od?.consumption |
/overview | consumption |
同上 |
| 费用总览Tab | ov.total_consumption |
/store-expense/overview | total_consumption |
analytics.bill_fact.consumption |
口径:一致 ✅
1.2 优惠
| 页面 | 前端变量 | API | API字段 | 数据源表.字段 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.discount |
/overview | discount |
analytics.bill_fact.discount_total |
| 老板驾驶舱 | od?.discount |
/overview | discount |
同上 |
| 费用总览Tab | ov.total_discount |
/store-expense/overview | total_discount |
同上 |
口径:一致 ✅
1.3 实收
| 页面 | 前端变量 | API | API字段 | 数据源表.字段 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.received |
/overview | received |
analytics.bill_fact.received_total |
| 老板驾驶舱 | od?.received |
/overview | received |
同上 |
| 费用总览Tab | ov.total_received |
/store-expense/overview | total_received |
analytics.mv_store_risk_rating_monthly.received |
| 利润瀑布 | wf.received |
/overview/profit-waterfall | received |
analytics.mv_store_risk_rating_monthly.received |
口径:一致 ✅ — bill_fact.received_total 汇总和物化视图汇总结果相同。
1.4 账单数
| 页面 | 前端变量 | API | API字段 | 数据源表.字段 |
|---|---|---|---|---|
| 总部驾驶舱 | od?.bill_count |
/overview | bill_count |
analytics.bill_fact (count(*)) |
| 老板驾驶舱 | ex?.total_bills |
/store-expense/overview | total_bills |
analytics.mv_store_risk_rating_monthly.bill_count |
口径:一致 ✅
1.5 客单价
| 页面 | 计算方式 | 值 |
|---|---|---|
| 总部驾驶舱 | avg(received_total) from bill_fact |
38.29 |
| 老板驾驶舱 | sum(received)/sum(bill_count) |
38.29 |
口径:一致 ✅ — 数学结果相同。
1.6 门店贡献利润(实际)
| 页面 | API | 计算方式 | 值 |
|---|---|---|---|
| 总部驾驶舱 | /store-expense/overview | sum(received) FILTER(费用匹配) - food_cost - operating_expense |
6,982,110.42 |
| 老板驾驶舱(指标卡) | 同上 | 同上 | 同上 |
| 老板驾驶舱(瀑布图) | /overview/profit-waterfall | sum(received) FILTER(has_expense) - food_cost - operating_expense |
同上 |
口径:一致 ✅(已修复)
1.7 食材成本
| 页面 | API | 计算方式 |
|---|---|---|
| 总部驾驶舱 | /store-expense/overview | sum(actual_food_cost) |
| 老板驾驶舱(瀑布图) | /overview/profit-waterfall | sum(COALESCE(actual_food_cost,0)) |
| 费用总览Tab | /store-expense/overview | 同总部 |
口径:一致 ✅ — sum(NULL) 忽略 vs sum(COALESCE(NULL,0)) 加0,结果相同。
1.8 费用率
| 页面 | 计算方式 | 值 |
|---|---|---|
| 总部驾驶舱 | sum(operating_expense)/matched_received*100 |
53.77% |
| 老板驾驶舱(瀑布图) | wf.total_expense/wf.received*100(matched口径) |
53.77% |
| 费用总览Tab | 同总部 | 53.77% |
口径:一致 ✅(已修复)
1.9 门店风险分布 / P0+P1门店 / 盈利亏损数
| 指标 | 页面 | API | 数据源 |
|---|---|---|---|
| 风险分布 | 总部/老板 | /stores/risk | mv_store_risk_rating_monthly.risk_level |
| P0/P1 | 总部/老板 | /stores/priority | mv_store_action_priority_deep_monthly |
| 盈利/亏损 | 总部/老板 | /store-expense/overview | count FILTER(actual_store_contribution > 0) |
口径:一致 ✅
2. 口径一致性保障原则
- 同一指标多页面展示时,必须使用同一数据源(物化视图或原始表,不能混用)
- 分母口径必须一致:如"费用率"分母必须统一为 matched_received(仅含费用匹配门店)
- FILTER vs COALESCE:
sum(x) FILTER(WHERE has_expense)与sum(COALESCE(x,0))在无NULL行时结果相同,但语义不同——FILTER排除整行,COALESCE只替换NULL值 - 物化视图 vs 原始表:优先用物化视图,避免直接查原始表(性能差 + 可能stale不一致)
- 新增页面时:如果复用已有指标,必须检查数据源是否一致,避免口径分裂
3. 已发现问题清单
已修复 ✅
| # | 问题 | 位置 | 修复方式 |
|---|---|---|---|
| 1 | 利润瀑布 store_contribution 口径不一致 | /overview/profit-waterfall | received等改为 FILTER(WHERE has_expense) |
| 2 | 瀑布图费率分母不一致 | 前端除法 | received改为matched口径后分母一致 |
| 3 | mv_overview_monthly 刷新缺失 | 刷新脚本 | 加入DELETE+INSERT步骤 |
| 4 | 优惠率/毛利率/会员占比硬编码为0 | /overview API | 修正SQL计算 |
| 5 | Schema前缀错误 | /channel API | 移除analytics.前缀 |
| 6 | 列名不存在 | /stores/risk等 | SELECT * 或0 AS替代 |
| 7 | 日期格式不匹配 | 考勤相关API | to_char改中文格式 |
| 8 | 客流-人力匹配在岗人数不合理 | /situational-awareness/correlation | 改用打卡数据解析 |
| 9 | 客流月度汇总vs日均未对齐 | 同上 | 客流除以30天 |
待确认 ⚠️
| # | 问题 | 位置 | 影响 | 建议 |
|---|---|---|---|---|
| 1 | KPI达成率利润口径不一致 | /analytics-enhanced/kpi | 利润率偏低~0.7pp | 分母改为matched_received |
| 2 | store-profit-ranking COALESCE导致无费用门店排名异常 | /overview/store-profit-ranking | 利润TOP5可能含无费用门店 | 加FILTER(has_expense) |
| 3 | StorePage公司均值硬编码 | StorePage.tsx:188 | 不随数据更新 | 改为API动态获取 |
| 4 | StorePage scorecard直接查bill_records | /stores/:code | 可能与物化视图不一致 | 改用物化视图 |
4. 口径检查方法论
4.1 新增指标时的检查流程
1. 该指标是否在其他页面已存在?
→ 是:检查数据源是否一致(表、字段、过滤条件)
→ 否:记录到溯源文档
2. 分子分母的过滤条件是否一致?
→ 如:费用率分母是否都用了matched_received
3. 是否用了物化视图?
→ 优先用物化视图,避免直接查原始表
4. 是否有NULL处理差异?
→ sum(x) vs sum(COALESCE(x,0)) 在有NULL行时结果不同
5. curl + psql 双向验证
→ API返回值与直查数据库一致
4.2 定期口径审计
1. 运行溯源文档中的"跨页面对比"部分
2. 对每个指标,在所有出现的页面验证值是否一致
3. 不一致的,定位差异原因(数据源、过滤条件、计算方式)
4. 修复并更新文档