fix: 统一利润瀑布口径,与费用总览API一致
profit-waterfall API的received/consumption/discount/store_contribution 改为仅计算has_expense门店(FILTER WHERE has_expense) 修复前: received=6441万(94家) store_contribution=770万 修复后: received=6369万(92家) store_contribution=698万 现在瀑布图和指标卡的贡献利润/食材率/费用率/贡献率完全一致 同时创建数据溯源审计文档,覆盖全部页面的指标溯源和口径对比
This commit is contained in:
@@ -1068,9 +1068,9 @@ router.get('/overview/profit-waterfall', async (req: AuthRequest, res) => {
|
||||
WHERE r.month_start = $1 AND r.received IS NOT NULL
|
||||
)
|
||||
SELECT
|
||||
round(sum(consumption)::numeric, 2) AS consumption,
|
||||
round(sum(discount)::numeric, 2) AS discount,
|
||||
round(sum(received)::numeric, 2) AS received,
|
||||
round(sum(consumption) FILTER (WHERE has_expense)::numeric, 2) AS consumption,
|
||||
round(sum(discount) FILTER (WHERE has_expense)::numeric, 2) AS discount,
|
||||
round(sum(received) FILTER (WHERE has_expense)::numeric, 2) AS received,
|
||||
round(sum(actual_food_cost)::numeric, 2) AS food_cost,
|
||||
round(sum(wage_expense)::numeric, 2) AS wage,
|
||||
round(sum(rent_expense)::numeric, 2) AS rent,
|
||||
@@ -1079,7 +1079,7 @@ router.get('/overview/profit-waterfall', async (req: AuthRequest, res) => {
|
||||
round(sum(delivery_commission_expense)::numeric, 2) AS commission,
|
||||
round(sum(card_fee_expense + repair_clean_expense)::numeric, 2) AS other_expense,
|
||||
round(sum(operating_expense)::numeric, 2) AS total_expense,
|
||||
round(sum(received) - sum(actual_food_cost) - sum(operating_expense), 2) AS store_contribution,
|
||||
round(sum(received) FILTER (WHERE has_expense) - sum(actual_food_cost) - sum(operating_expense), 2) AS store_contribution,
|
||||
count(*) AS covered_stores,
|
||||
count(*) FILTER (WHERE has_expense) AS stores_with_expense
|
||||
FROM full_scope
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
# 全页面数据溯源审计报告
|
||||
|
||||
> 目标:逐页面、逐指标追溯显示名称 → API → SQL → 数据源表字段,标出跨页面重复指标口径是否一致。
|
||||
|
||||
## 一、页面与 API 总览
|
||||
|
||||
| 页面 | 文件 | 调用的 API |
|
||||
|------|------|-----------|
|
||||
| 总部驾驶舱 | DashboardPage.tsx | /overview, /overview/daily, /stores/risk, /stores/priority, /tasks/loop-health, /stores/quadrant, /platform/economics, /situational-awareness/alerts, /store-expense/overview, /overview/yoy, /overview/mom, /overview/trend, /overview/profit-trend |
|
||||
| 老板驾驶舱 | BossPage.tsx | /overview, /overview/daily, /store-expense/overview, /overview/profit-waterfall, /stores/risk, /stores/priority, /cost-analysis/store-overview, /store-expense/expense-structure, /overview/store-profit-ranking, /overview/profit-opportunity |
|
||||
| 门店工作台 | StorePage.tsx | /stores/risk, /stores/priority, /tasks/stores/:code/daily-card, /tasks, /stores/:code/daily, /tasks/followup, /sku/attach, /sku/abc, /stores/:code, /situational-awareness/health-score, /stores/:code/meal-period, /stores/:code/category-mix, /stores/:code/cost, /stores/:code/member, /stores/:code/anomalies, /stores/:code/staffing |
|
||||
| 成本分析 | CostPage.tsx | /cost/comparison, /cost/inventory, /cost/category-benchmark |
|
||||
| 成本分析(Tab) | cost-analysis/*.tsx | /cost-analysis/overview, /category-comparison, /margin-deviation, /variance-top, /menu-engineering, /profitability, /pricing, /store-overview, /store-ranking, /bom-*, /packaging-*, /material-*, /data-quality, /unmatched-* |
|
||||
| 费用分析(Tab) | store-expense/*.tsx | /store-expense/overview, /expense-structure, /store-ranking, /store-contribution, /break-even, /loss-diagnosis, /delivery-commission, /rent-risk, /fixed-variable, /efficiency, /store-evaluation |
|
||||
| 风险监控 | RiskPage.tsx | /risk/anomaly, /risk/zero-received, /risk/cashier |
|
||||
| 会员复购 | MemberPage.tsx | /member/comparison, /member/repeat |
|
||||
| SKU分析 | SKUPage.tsx | /sku/abc, /sku/category |
|
||||
| 菜单工程 | MenuEngineeringPage.tsx | /analytics-enhanced/menu-engineering/actions |
|
||||
| 产品生命周期 | ProductLifecyclePage.tsx | /product/products, /product/reviews/overview, /product/reviews |
|
||||
| BOM穿透 | BomPenetrationPage.tsx | /central-kitchen/bom-penetration |
|
||||
| 分销对账 | DistributionReconciliationPage.tsx | /distribution/reconciliation |
|
||||
| 生产计划 | ProductionPlanPage.tsx | /sales-driven/production-plan |
|
||||
| 任务闭环 | TasksPage.tsx | /tasks |
|
||||
| 数据导入 | DataImportPage.tsx | /product/import-logs, /product/quality-rules |
|
||||
| 本体浏览 | OntologyPage.tsx | /tasks/ontology/* |
|
||||
|
||||
---
|
||||
|
||||
## 二、核心指标溯源与口径对比
|
||||
|
||||
### 2.1 营业收入(消费金额)
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|
||||
|------|---------|-----|---------|---------|-------------|
|
||||
| 总部驾驶舱 | `od?.consumption` | /overview | `consumption` | `sum(consumption)` from bill_fact | analytics.bill_fact.consumption |
|
||||
| 老板驾驶舱 | `od?.consumption` | /overview | `consumption` | 同上 | 同上 |
|
||||
| 费用总览Tab | `ov.total_consumption` | /store-expense/overview | `total_consumption` | `sum(consumption)` from bill_fact CTE | analytics.bill_fact.consumption |
|
||||
|
||||
**口径:一致 ✅** — 三个页面均来自 `analytics.bill_fact.consumption` 的月度汇总。
|
||||
|
||||
### 2.2 优惠
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|
||||
|------|---------|-----|---------|---------|-------------|
|
||||
| 总部驾驶舱 | `od?.discount` | /overview | `discount` | `sum(discount_total)` from bill_fact | analytics.bill_fact.discount_total |
|
||||
| 老板驾驶舱 | `od?.discount` | /overview | `discount` | 同上 | 同上 |
|
||||
| 费用总览Tab | `ov.total_discount` | /store-expense/overview | `total_discount` | `sum(discount_total)` from bill_fact CTE | analytics.bill_fact.discount_total |
|
||||
|
||||
**口径:一致 ✅**(已修复,BossPage 之前用 `ex?.total_discount` 也一致)
|
||||
|
||||
### 2.3 实收
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|
||||
|------|---------|-----|---------|---------|-------------|
|
||||
| 总部驾驶舱 | `od?.received` | /overview | `received` | `sum(received_total)` from bill_fact | analytics.bill_fact.received_total |
|
||||
| 老板驾驶舱 | `od?.received` | /overview | `received` | 同上 | 同上 |
|
||||
| 费用总览Tab | `ov.total_received` | /store-expense/overview | `total_received` | `sum(r.received)` from mv_store_risk_rating_monthly | analytics.mv_store_risk_rating_monthly.received |
|
||||
| 利润瀑布 | `wf.received` | /overview/profit-waterfall | `received` | `sum(r.received)` from mv_store_risk_rating_monthly | analytics.mv_store_risk_rating_monthly.received |
|
||||
|
||||
**口径:一致 ✅**(已修复)— `bill_fact.received_total` 汇总和 `mv_store_risk_rating_monthly.received` 汇总结果相同(均为 64,409,339.09),因为后者物化视图就来自前者。
|
||||
|
||||
### 2.4 账单数
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | SQL来源 | 数据源表.字段 |
|
||||
|------|---------|-----|---------|---------|-------------|
|
||||
| 总部驾驶舱 | `od?.bill_count` | /overview | `bill_count` | `count(*)` from bill_fact | analytics.bill_fact |
|
||||
| 老板驾驶舱 | `ex?.total_bills` | /store-expense/overview | `total_bills` | `sum(bill_count)` from mv_store_risk_rating_monthly | analytics.mv_store_risk_rating_monthly.bill_count |
|
||||
|
||||
**口径:一致 ✅** — 值均为 1,682,360。
|
||||
|
||||
### 2.5 客单价
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `od?.avg_bill_value` | /overview | `avg_bill_value` | `avg(received_total)` from bill_fact = 38.29 |
|
||||
| 老板驾驶舱 | `ex?.avg_bill_value` | /store-expense/overview | `avg_bill_value` | `sum(received)/sum(bill_count)` = 38.29 |
|
||||
|
||||
**口径:一致 ✅** — 数学结果相同。
|
||||
|
||||
### 2.6 优惠率
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `od?.discount_rate_pct` | /overview | `discount_rate_pct` | `avg(discount_total/consumption*100)` from bill_fact = 19.52% |
|
||||
| 老板驾驶舱 | 无(不显示此指标) | - | - | - |
|
||||
|
||||
**口径:N/A** — 仅总部驾驶舱显示。
|
||||
|
||||
### 2.7 理论毛利率
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `od?.theoretical_margin_pct` | /overview | `theoretical_margin_pct` | `sum(theoretical_profit)/sum(received)*100` from bill_fact = 61.84% |
|
||||
|
||||
**口径:N/A** — 仅总部驾驶舱显示。(已修复,之前硬编码为0)
|
||||
|
||||
### 2.8 会员占比
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `od?.member_share_pct` | /overview | `member_share_pct` | `sum(received_total) FILTER(member_id非空)/sum(received_total)*100` = 14.25% |
|
||||
|
||||
**口径:N/A** — 仅总部驾驶舱显示。(已修复,之前硬编码为0)
|
||||
|
||||
### 2.9 门店贡献利润(实际)
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|
||||
|------|---------|-----|---------|---------|-----|
|
||||
| 总部驾驶舱 | `ex?.actual_net_profit` | /store-expense/overview | `actual_net_profit` | `sum(received) FILTER(费用匹配) - sum(food_cost) - sum(operating_expense)` | 6,982,110.42 |
|
||||
| 老板驾驶舱(指标卡) | `ex?.actual_net_profit` | /store-expense/overview | `actual_net_profit` | 同上 | 6,982,110.42 |
|
||||
| 老板驾驶舱(瀑布图) | `wf.store_contribution` | /overview/profit-waterfall | `store_contribution` | `sum(received) - sum(COALESCE(food_cost,0)) - sum(COALESCE(operating_expense,0))` | **7,703,472.16** |
|
||||
|
||||
**口径:不一致 ❌** — 瀑布图用 COALESCE(...,0) 包含2家无费用门店,导致利润虚高72万。需修复 profit-waterfall API。
|
||||
|
||||
### 2.10 贡献率(实际)
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|
||||
|------|---------|-----|---------|---------|-----|
|
||||
| 总部驾驶舱 | `ex?.actual_net_margin_pct` | /store-expense/overview | `actual_net_margin_pct` | `(matched_received - food_cost - operating_expense)/matched_received*100` | 10.96% |
|
||||
| 老板驾驶舱(指标卡) | `ex?.actual_net_margin_pct` | /store-expense/overview | `actual_net_margin_pct` | 同上 | 10.96% |
|
||||
| 老板驾驶舱(瀑布图) | 前端计算 `wf.store_contribution/wf.received*100` | /overview/profit-waterfall | 前端除法 | `7703472/64409339*100` | **11.96%** |
|
||||
|
||||
**口径:不一致 ❌** — 同 2.9,瀑布图口径不同。
|
||||
|
||||
### 2.11 食材成本
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `ex?.total_food_cost` | /store-expense/overview | `total_food_cost` | `sum(actual_food_cost)` from mv_store_operating_expense_monthly |
|
||||
| 老板驾驶舱(瀑布图) | `wf.food_cost` | /overview/profit-waterfall | `food_cost` | `sum(COALESCE(actual_food_cost,0))` — 含2家0值门店 |
|
||||
| 费用总览Tab | `ov.total_food_cost` | /store-expense/overview | `total_food_cost` | 同总部 |
|
||||
|
||||
**口径:一致 ✅** — 2家无费用门店的 food_cost 为 NULL,`sum(NULL)` 忽略,`sum(COALESCE(NULL,0))` 加0,结果相同。
|
||||
|
||||
### 2.12 食材成本率
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|
||||
|------|---------|-----|---------|---------|-----|
|
||||
| 总部驾驶舱 | `ex?.actual_food_cost_rate_pct` | /store-expense/overview | `actual_food_cost_rate_pct` | `sum(food_cost)/matched_received*100` | 35.26% |
|
||||
| 老板驾驶舱(瀑布图) | 前端计算 `wf.food_cost/wf.received*100` | /overview/profit-waterfall | 前端除法 | `22459074/64409339*100` | **34.87%** |
|
||||
|
||||
**口径:不一致 ❌** — 分母不同(matched_received 6369万 vs all_received 6441万)。
|
||||
|
||||
### 2.13 经营费用
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `ex?.total_expense` | /store-expense/overview | `total_expense` | `sum(operating_expense)` — NULL被sum忽略 |
|
||||
| 老板驾驶舱(瀑布图) | `wf.total_expense` | /overview/profit-waterfall | `total_expense` | `sum(COALESCE(operating_expense,0))` — 2家为0 |
|
||||
| 费用总览Tab | `ov.total_expense` | /store-expense/overview | `total_expense` | 同总部 |
|
||||
|
||||
**口径:一致 ✅** — sum忽略NULL vs COALESCE加0,结果相同。
|
||||
|
||||
### 2.14 费用率
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 | 值 |
|
||||
|------|---------|-----|---------|---------|-----|
|
||||
| 总部驾驶舱 | `ex?.overall_expense_rate_pct` | /store-expense/overview | `overall_expense_rate_pct` | `sum(operating_expense)/matched_received*100` | 53.77% |
|
||||
| 老板驾驶舱(瀑布图) | 前端计算 `wf.total_expense/wf.received*100` | /overview/profit-waterfall | 前端除法 | `34246793/64409339*100` | **53.17%** |
|
||||
| 费用总览Tab | `ov.overall_expense_rate_pct` | /store-expense/overview | `overall_expense_rate_pct` | 同总部 | 53.77% |
|
||||
|
||||
**口径:不一致 ❌** — 瀑布图分母含全部94家。
|
||||
|
||||
### 2.15 人工费用 / 人工费率
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `ex?.total_wage` / `ex?.overall_wage_rate_pct` | /store-expense/overview | `total_wage` / `overall_wage_rate_pct` | `sum(wage_expense)` / `sum(wage)/matched_received*100` |
|
||||
| 老板驾驶舱(瀑布图) | `wf.wage` | /overview/profit-waterfall | `wage` | `sum(COALESCE(wage_expense,0))` |
|
||||
| 费用总览Tab | `ov.total_wage` / `ov.overall_wage_rate_pct` | /store-expense/overview | 同总部 | 同总部 |
|
||||
|
||||
**金额口径:一致 ✅** — sum忽略NULL vs COALESCE加0结果相同。
|
||||
**费率口径:瀑布图不一致 ❌** — 前端用 `wf.wage/wf.received*100`(分母含94家)vs store-expense用 `matched_received`(92家)。
|
||||
|
||||
### 2.16 房租费用 / 房租费率
|
||||
|
||||
同 2.15,金额一致,费率瀑布图分母不一致。
|
||||
|
||||
### 2.17 水电费用 / 水电费率
|
||||
|
||||
同 2.15,金额一致,费率瀑布图分母不一致。
|
||||
|
||||
### 2.18 外卖佣金
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `ex?.total_commission` | /store-expense/overview | `total_commission` | `sum(delivery_commission_expense)` |
|
||||
| 老板驾驶舱(瀑布图) | `wf.commission` | /overview/profit-waterfall | `commission` | `sum(COALESCE(delivery_commission_expense,0))` |
|
||||
|
||||
**口径:一致 ✅** — 金额相同。
|
||||
|
||||
### 2.19 门店数
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `riskRows.length` | /stores/risk | count of rows | `count(*)` from mv_store_risk_rating_monthly |
|
||||
| 老板驾驶舱 | `ex?.total_stores` | /store-expense/overview | `total_stores` | `count(*)` from full_scope (mv_store_risk_rating_monthly) |
|
||||
|
||||
**口径:一致 ✅** — 均为94家。
|
||||
|
||||
### 2.20 盈利/亏损门店数
|
||||
|
||||
| 页面 | 前端变量 | API | API字段 | 计算方式 |
|
||||
|------|---------|-----|---------|---------|
|
||||
| 总部驾驶舱 | `ex?.profitable_stores` / `ex?.loss_stores` | /store-expense/overview | `profitable_stores` / `loss_stores` | `count(*) FILTER(actual_store_contribution>0)` / `count(*) FILTER(<=0 AND received>0)` |
|
||||
| 老板驾驶舱 | 同上 | 同上 | 同上 | 同上 |
|
||||
|
||||
**口径:一致 ✅** — 盈利78家/亏损13家。
|
||||
|
||||
### 2.21 门店风险分布
|
||||
|
||||
| 页面 | 前端变量 | API | 数据源 |
|
||||
|------|---------|-----|--------|
|
||||
| 总部驾驶舱 | `riskSummary` | /stores/risk | analytics.mv_store_risk_rating_monthly.risk_level |
|
||||
| 老板驾驶舱 | `riskSummary` | /stores/risk | 同上 |
|
||||
|
||||
**口径:一致 ✅**
|
||||
|
||||
### 2.22 P0/P1 门店
|
||||
|
||||
| 页面 | 前端变量 | API | 数据源 |
|
||||
|------|---------|-----|--------|
|
||||
| 总部驾驶舱 | `priorityRows` | /stores/priority | analytics.mv_store_action_priority_deep_monthly |
|
||||
| 老板驾驶舱 | `priorityRows` | /stores/priority | 同上 |
|
||||
|
||||
**口径:一致 ✅**
|
||||
|
||||
### 2.23 成本异常分布
|
||||
|
||||
| 页面 | 前端变量 | API | 数据源 |
|
||||
|------|---------|-----|--------|
|
||||
| 老板驾驶舱 | `costOv.red_count` 等 | /cost-analysis/store-overview | analytics.mv_store_theoretical_actual_cost_monthly |
|
||||
| 成本分析Tab | 同上 | 同上 | 同上 |
|
||||
|
||||
**口径:一致 ✅**
|
||||
|
||||
### 2.24 利润机会池
|
||||
|
||||
| 页面 | 前端变量 | API | 数据源 |
|
||||
|------|---------|-----|--------|
|
||||
| 老板驾驶舱 | `profitOpp` | /overview/profit-opportunity | analytics.mv_store_risk_rating_monthly + mv_store_operating_expense_monthly |
|
||||
|
||||
**口径:N/A** — 仅老板驾驶舱显示。
|
||||
|
||||
### 2.25 日度趋势
|
||||
|
||||
| 页面 | 前端变量 | API | 数据源 |
|
||||
|------|---------|-----|--------|
|
||||
| 总部驾驶舱 | `dailyRows` | /overview/daily | analytics.mv_overview_daily 或 bill_fact |
|
||||
| 老板驾驶舱 | `dailyRows` | /overview/daily | 同上 |
|
||||
|
||||
**口径:一致 ✅**
|
||||
|
||||
---
|
||||
|
||||
## 三、发现的问题汇总
|
||||
|
||||
### 问题1:利润瀑布 store_contribution 口径不一致 ❌
|
||||
|
||||
**位置**:`/overview/profit-waterfall` API (`data.ts:1082`)
|
||||
|
||||
**现状**:
|
||||
```sql
|
||||
round(sum(received) - sum(actual_food_cost) - sum(operating_expense), 2) AS store_contribution
|
||||
```
|
||||
- `sum(received)` = 64,409,339(94家)
|
||||
- `sum(actual_food_cost)` = 22,459,074(92家,NULL被忽略)
|
||||
- `sum(operating_expense)` = 34,246,793(92家,NULL被忽略)
|
||||
- 结果 = 7,703,472(含2家无费用门店的实收429万作为"利润")
|
||||
|
||||
**正确值**(与 store-expense/overview 一致):6,982,110(仅92家匹配门店)
|
||||
|
||||
**影响**:BossPage 利润瀑布图和占比条显示的"门店贡献利润"比指标卡多72万,贡献率高1个百分点。
|
||||
|
||||
### 问题2:利润瀑布各项费率分母不一致 ❌
|
||||
|
||||
**位置**:BossPage.tsx 前端计算 (line 296-318)
|
||||
|
||||
**现状**:前端用 `wf.received`(64,409,339,94家)做分母计算食材成本率、费用率、贡献率,但 store-expense/overview 用 `matched_received`(63,687,977,92家)做分母。
|
||||
|
||||
| 指标 | 瀑布图口径 | store-expense口径 | 差异 |
|
||||
|------|-----------|------------------|------|
|
||||
| 食材成本率 | 34.87% | 35.26% | 0.39pp |
|
||||
| 费用率 | 53.17% | 53.77% | 0.60pp |
|
||||
| 贡献率 | 11.96% | 10.96% | 1.00pp |
|
||||
|
||||
### 问题3:mv_overview_monthly 刷新机制不完整 ⚠️
|
||||
|
||||
**现状**:`mv_overview_monthly` 是普通表(非物化视图),之前刷新脚本未包含它的更新步骤,导致数据导入后该表不更新。
|
||||
|
||||
**已修复**:刷新脚本已加入 DELETE+INSERT 步骤。
|
||||
|
||||
---
|
||||
|
||||
## 四、修复方案
|
||||
|
||||
### 修复问题1+2:统一利润瀑布口径
|
||||
|
||||
将 `/overview/profit-waterfall` 的 `store_contribution` 和 `received` 改为仅计算有费用门店,与 `/store-expense/overview` 保持一致。
|
||||
|
||||
**修改文件**:`server/src/routes/data.ts` profit-waterfall API
|
||||
|
||||
**修改内容**:
|
||||
1. `received` → `sum(received) FILTER (WHERE has_expense)`
|
||||
2. `store_contribution` → `sum(received) FILTER (WHERE has_expense) - sum(actual_food_cost) - sum(operating_expense)`
|
||||
3. `consumption` 和 `discount` 也改为 `FILTER (WHERE has_expense)` 保持同口径
|
||||
|
||||
这样瀑布图的 received、food_cost、expense、contribution 全部基于92家匹配门店,与 store-expense/overview 完全一致。
|
||||
Reference in New Issue
Block a user