编辑 | blame | 历史 | 原始文档

中口径排名「同比不对」+ 城市客运页列错位:根因与长效方案(2026-09-18)

结论先行:
1. 中口径排名的增速错,不是公式错,是「去年同期基数残缺也照算」。 2025 年三处数据缺失/污染,被静默当成 0 或错值,全省 1-8 月基数只有 18131.0(应为 29796.71),所以 2026 累计同比算出 +73.89%(真值 +5.81%),「增速排名」整块不可信。
2. 方案一(把城市客运 T 列分母 AJ 改成 AK)长远不可行:它只对「8 月」这一个报表期成立,9 月报表期要 1-9 月累计,分母还得再手改母版——正是要消灭的「每月改模板」。
3. 正确做法是三条腿一起改:**数据补全(治本)+ 同比计算带完备性校验(防复发)+ 城市客运页结构归一(去特例)**。

证据文件:_tmp\_qa_out\step3g_summary.xlsx、step3g_midRank.xlsx、step3g_midDetail.xlsx、_now_rank.txt、_ding_rank.txt、_ding_mid_head.txt、_mother_rank.txt。
业务基线(人工定稿):D:\05_数据分类\汇总表\8月汇总定稿\2026年8月客运量、货运量定稿.xlsx。


一、中口径排名同比为什么不对(已逐项验证)

1.1 现象(2026-08 报表期)

位置 程序算出 定稿/正确值 偏差
累计块 全省 同比(M3) +73.89% +5.81% 差 68 个百分点
累计块 武汉 同比(M4) +12.07% +4.65% 差 7.4 个百分点
累计块 黄石 +105.41% +7.85% —
累计块 十堰 +192.30% +2.17% —
累计块 襄阳 +107.07% +5.63% —
累计块 咸宁 +189.54% +17.00% —
累计块 潜江 +766.85% −2.86% —
当月块 全省 同比(M24) +67.63% −0.67% —

值本身是对的(累计 31528.0607、当月 4003.5701 与定稿完全一致),**只有同比错** —— 这正是「分子对、分母残」的典型特征。

1.2 基数账(决定性证据)

定稿 2025 年 1-8 月中口径累计 = 29796.71(万元人次),逐项:

维度 1月 2月 3月 4月 5月 6月 7月 8月 1-8月合计
公路班线 1688.1442 1719.8742 1721.8891 1824.67 1811.8188 1718.0442 1781.8881 1784.7773 14051.1159
城际城乡公交 1143.83 1146.53 1242.29 1288.71 1385.12 1377.95 1344.24 1350.08 10278.75
城际城乡巡游出租 409.54 448.64 417.98 429.77 494.11 438.88 566.86 603.64 3809.42
城际城乡网约车 142.54 152.48 167.08 194.78 230.58 206.93 271.02 292.02 1657.43
合计 3384.0542 3467.5242 3549.2391 3737.93 3921.6288 3741.8042 3964.0081 4030.5173 29796.71

程序实际用到的基数 = 31528.0606 / 1.7389 = 18131.0。

差额 11665.7 = 10278.75(公交)+ 1514.89(网约车 2-8 月)− 127.98(出租 6 月多算)→ 完全对得上。

1.3 三处数据缺陷(逐条已查实)

缺陷① city_bus_monthly.passenger_chengxiang 在 2025 年全部为 0/负

SELECT report_period, SUM(passenger_chengxiang), SUM(passenger_volume-passenger_city)
FROM city_bus_monthly WHERE report_period LIKE '2025-%' GROUP BY report_period;
-- 2025-01: -0.341  vs  1143.83   ← 存储列是 0,实际应为 1143.83
-- 2025-08: -0.114  vs  1350.08
-- 2026-01: 1391.19 vs  1391.19   ← 2026 正常
  • 后果:中口径公交维度 2025 全年为 0 → 1-8 月少 10278.75 万人次;导出的「中口径明细」公交累计同比直接算成 −28577.71%(分母 −0.407)。
  • 兜底关系已验证逐月与定稿一致:**城际城乡 = 总客运量 − 城市内客运量**(例:2025-01 15079.24−13935.41=1143.83 ✓)。

缺陷② wyc_order_monthly.pin_* 在 2025-02~08 为 NULL

SELECT report_period, pin_k FROM wyc_order_monthly WHERE report_period LIKE '2025%';
-- 2025-01: 2467.79
-- 2025-02 .. 2025-08: NULL   ← 缺
-- 2025-09 .. 2025-12: 有值
-- 2025-01 的 2467.79 与 wyc_total_monthly 完全相同(同源)
  • WycSplitCalc.loadMonthlyInputFromDb() 只读订单表的 pin 列(WycSplitCalc.java:258-261),pin 读成 0 → calc() 在 WycSplitCalc.java:100-102 抛异常 → loadMidClassMap() 的 catch 直接 continue(ReportExportService.java:2429-2431)→ 该月网约车维度整月丢失。
  • 后果:网约车城乡 2025 只算了 1 月(142.54),2-8 月缺失 1514.89 万人次。
  • 另注:wyc_total_monthly(pin 专表)里 2025-02~08 数据是全的,只是没同步到订单表。

缺陷③ city_taxi_monthly 2025-06 是 2025-07 的副本

-- 逐市州比对 2025-06 与 2025-07:17 个市州客运量/周转量 完全逐值相同
-- 全省 2025-06 程序值 566.86,定稿 438.88,多算 127.98
  • 属于重复导入/错期导入,需要用正确的 6 月源文件重导。

1.4 已排除的误判

  • 母版/定稿的中口径公式**没有错**(早前「引错页」是控制台中文乱码误判)。
  • loadMidClassMap() 目前**四维都在**(班线 / 公交 / 巡游出租 / 网约车,ReportExportService.java:2351-2437);今日《汇总表三条主线修复方案》里「只装了班线+公交两维」的说法已过期。
  • 中口径排名 的取值口径(维度 0 = 四维合计)**与定稿一致**,无需改口径。

二、城市客运页列错位(与方案一相关)

2.1 母版现状(docs\生成汇总大表\2026年8月道路运输量汇总表.xlsx → 城市客运页,第 2 行表头)

列 表头 说明
V/X/Z/AB 2025年1月/2月/3月/4月 文字正常
AD / AF / AH 45778 / 45809 / 45839 日期序列号,不是「2025年5/6/7月」
AJ 2025年1-7月累计 夹层辅助列,插在了 2025 月度块中间
AK 45870 日期序列号,才是真正的「2025年8月」
AL 8月同比 对应 AK

2026 侧同样脏:G/I/K/M/O/Q = 46082 / 46113 / 46143 / 46174 / 46204 / 46235(日期序列号)。

累计同比公式:

城市客运!T4 = S4/(V4+X4+Z4+AB4+AD4+AF4+AH4+AJ4)-1     ← 分母 = (1-7月) + (1-7月累计) = 2×(1-7月)
其它 8 页!T4 = S4/SUM(V4+X4+Z4+AB4+AD4+AF4+AH4+AJ4)-1  ← 分母 = 1-8月累计,正确

即:**只有城市客运页**因为 AJ 夹层列,分母少了「2025年8月」。

2.2 为什么「方案一」长远不行

# 问题 说明
1 只对 8 月成立 9 月报表期要 1-9 月累计,分母需再加 AM(真正 2025年9月);10 月再加……每个月都要手改母版公式。这就是「每个月做模板」的变体。
2 夹层列会让所有「按列序号」的处理整体错位 1 列 applySummaryReferenceLayout()(ReportExportService.java:3535)是按**列序号**套用列宽/隐藏标记的。你已经在参照件里删掉 AJ → 生成件从 AJ 之后所有列的列宽/隐藏标记都错位。
3 表头本身不是文字 AD/AF/AH/AK 是日期序列号,任何「按表头文字匹配列」的长效方案在这个页会直接失效。所以必须先规范表头。
4 参照件与母版结构不一致 删 AJ 后,参照件 36 个 #REF!(T4:T39),列宽映射基准也变了。

三、长效方案

A. 数据侧(治本,一次做完)

# 动作 具体做法 验收
A1 回填 2025 全年公交「城际城乡」 UPDATE city_bus_monthly SET passenger_chengxiang = passenger_volume - passenger_city WHERE report_period LIKE '2025-%' AND (passenger_chengxiang IS NULL OR passenger_chengxiang <= 0);周转量同法 2025 各月全省 = 1143.83/1146.53/1242.29/1288.71/1385.12/1377.95/1344.24/1350.08…
A2 回填 2025-02~08 网约车 pin 从 wyc_total_monthly 同步 pin_k/pin_ck/pin_z/pin_cz 到 wyc_order_monthly 同期 2025 全年 pin 齐全
A3 重导 2025-06 出租 用正确的 6 月源文件重导 city_taxi_monthly 2025-06 全省 = 438.88(现 566.86)

B. 代码侧(防复发,核心是「不齐全就不算」)

# 改动点 内容
B1 loadMidClassMap() dim2 存储的「城际城乡」≤0 时,用 总量 − 城市内 兜底(city_bus_monthly 一行内相减后再累加)
B2 WycSplitCalc.loadMonthlyInputFromDb() 订单表 pin 全空时回落 wyc_total_monthly(本例 2025-02~08 即可自动修好);两边都缺才抛异常
B3 midCumClass() / midClassVal() 返回值改为「值 + 命中月份数」;**同比只在「去年同月齐全」时计算**,不齐全一律留空(现在缺月被静默当 0 → 基数变小 → 同比虚高)
B4 导出前置「基数体检」 三条规则:①去年同月该维度=0;②某月逐市州值与相邻月完全相同(重复导入特征);③去年同月市州行数 < 17。命中则:写后端日志 + 页面弹窗 + 生成件附一张《数据缺失清单》页
B5 日志 loadMidClassMap() 里 catch → continue 改成记录「期 + 异常原因」清单,随导出日志输出(现在完全静默)

C. 结构侧(城市客运页归一,消除特例)

# 动作
C1 把 AJ(2025年1-7月累计)**移出 2025 月度块**(和 U 列这类辅助列放一起,或直接删除),使城市客运页 V..AJ = 2025年1月…8月,与其它 8 页完全同构。**在 WPS/Excel 里整列删**,让全表引用自动调整。
C2 表头文字化:G/I/K/M/O/Q、AD/AF/AH/AK 由日期序列号改成「2026年3月…」「2025年5月/6月/7月/8月」
C3 累计同比分母不写死列清单:由程序**每次按表头定位「去年 M 月」列**后重写公式(=S4/SUM(V4:去年M月列4)-1,注意只累加奇数列),9 月/10 月自动跟着走,母版不用再动
C4 applySummaryReferenceLayout() 改为**按表头文字匹配列**再套列宽/隐藏;参照件加减列不再错位

D. 报表侧

# 动作
D1 「增速排名」只在同比齐全时排名;否则该块标注「去年同期基数缺失,暂不排名」,避免用假增速排出假名次

四、验收基线(2026-08 报表期,中口径排名累计块)

市州 应为(定稿) 现在(程序)
全省 +5.81% +73.89%
武汉 +4.65% +12.07%
黄石 +7.85% +105.41%
十堰 +2.17% +192.30%
宜昌 −15.62% +4.28%
襄阳 +5.63% +107.07%
荆州 +36.30% +42.74%
黄冈 +7.64% +147.99%
咸宁 +17.00% +189.54%
恩施 +13.78% +55.88%
仙桃 +17.23% +241.89%
潜江 −2.86% +766.85%
天门 +8.99% +282.34%
林区 −34.87% −32.18%

其余验收点:
- 中口径明细 公交行累计同比不再出现 −28577% 这种数;
- 城市客运 页累计同比与该页「城市汇总」口径一致(不再是 −43% 对 +0.12%);
- 独立导出的《生成_中口径排名》与汇总大表「中口径排名」页逐格一致。


五、建议执行顺序

  1. A1/A2/A3 数据回填(半小时内可完成,做完中口径排名同比立即正确);
  2. B2、B1 代码兜底(防止同类缺失再次静默生效);
  3. B3、B4、B5 完备性校验(长效防复发 + 日志可视);
  4. C1~C4 城市客运页归一(改了母版,需要和业务确认后一次性做,改完 9 月报表期不用再手改);
  5. D1 报表措辞。