做供应链分析这十几年,我在帆软和九数云的项目里见过太多“准时交付率虚高”的报表。管理者看着仪表板上95%的OTD沾沾自喜,但仓库那边天天在催货、客户投诉不断。数据不会骗人,但数据可以被“洗”得很漂亮。问题出在根上,不是BI平台算错了,而是清洗环节把真正的业务问题给洗没了。这篇文章不是教你“怎样把缺失值删掉”的通用教程,我会把真实项目里踩过的坑、用过的判断逻辑、以及不同业务场景下的取舍一一拆开。
我在2023年初接手过一个华东云仓客户的OTD分析项目。客户用的ERP是SAP,WMS是自研系统,还有一套供应商门户。三套系统的“实际交付日期”字段对应了三个完全不同的时间点:SAP里是财务过账时间、WMS里是仓库签收时间、供应商门户里是物流签收单回传时间。同一个订单在三套系统里差了整整3天。
这就是我想在第一部分先讲清楚的核心结论,OTD数据清洗的本质,不是格式统一、缺失值填充这些技术动作,而是把你对“准时交付”的业务定义精准翻译成一整套可执行的数据规则。你定义不清“什么叫交付”,后面所有的清洗操作都是在制造精确的错误。
以我的项目经验来看,真正影响OTD分析质量的清洗决策有三个层级:
| 决策层级 | 典型问题 | 错误做法 | 正确做法 |
|---|---|---|---|
| 定义层 | “实际交付日期”用哪个系统的时间? | 取最早的或随便取一个 | 和业务方确认“交付完成”的判定节点,统一锚定一个字段 |
| 规则层 | 承诺日期被修改过,取哪个版本? | 取最新版本 | 保留修改历史,建立“首次承诺”和“最终承诺”双口径 |
| 执行层 | 缺失值直接删掉还是填充? | 一刀切删除 | 根据订单金额分级处理,高价值订单走人工确认流程 |

这个核心结论如果你没有先想明白,后面所有的清洗步骤都是在原地打转。我见过有团队花了两周写了一整套清洗脚本,最后发现清洗完的数据连“承诺交付日期”的字段都选错了,他们把供应商端上次修改日期和首次承诺日期搞混了。所以别急着动手,先把业务定义搞清楚。
先说一个我在实际项目中总结出的经验规律:只要你的供应链涉及两个以上系统、三个以上供应商、四种以上物料品类,你的OTD原始数据100%是“脏”的。这不是预估,是必然。原因不复杂,我们来看一组我实际统计过的数据。
一个典型的品牌方供应链数据流是这样的:采购订单在ERP系统创建,收货在WMS完成,物流信息在TMS流转,对账结算又回到ERP。这四个环节的数据结构、字段定义、更新频率完全不同。以我服务过的一个快消品客户为例,他们的ERP订单表有47个字段,WMS收货表有32个字段,但两个表之间只有“采购订单号”一个关联字段,而且WMS那边有13%的订单使用了手动录入的子编码。
这就是说,在数据集成阶段你就有13%的订单可能因为编码不匹配而变成“孤儿数据”。这些订单在OTD分析里要么被当成“未交付”,要么直接被清洗脚本丢弃。两种情况都会导致最终的准时交付率数字失真。
再说一个很多人不愿意承认但普遍存在的问题:人为修改。我曾在一次数据回溯分析里发现,某个供应商的准时交付率在季度末最后一周会奇迹般地从72%飙升到94%。后来查了系统的操作日志才知道,采购员在季度末集中批量修改了“承诺交付日期”,把那些已经逾期的订单承诺日期往后推了一两周。
这种情况在BI平台的清洗流程里极难被自动发现,因为系统只看到一个新的日期值,看不到改动的痕迹。如果不保留修改日志、不加时间序列校验,你的OTD报表实际上是一份被操作过的数据快照,不是真实业务表现。

这也是一个高频问题。有些WMS系统的时间戳精确到秒,有些老的TMS接口只返回日期。你在BI平台做数据合并的时候,按日期做匹配会出现一种非常隐蔽的问题:同一天的订单,系统A记录的是23:59:59发出去的,系统B的日期已经是第二天,计算出来的OTD差了一整天。
我在一个跨境物流项目里就遇到过,海运的ETA时间只有日期、没有小时的粒度,而仓库签收时间精确到分钟。结果全部同步装船的订单,有一半被系统判定为“延迟1天”。你如果不了解这个背景,光是跑一个数据清洗脚本,根本发现不了这个逻辑问题。
这部分是我的真实经验浓缩。下面这四个误区,我在至少三个不同的项目里反复遇到过,而且每次都是同样的原因,团队把数据清洗当成了纯技术操作,没有理解业务逻辑。
这是最常见也危害最大的误区。绝大多数初级BI分析师在面对缺失值时的第一反应是“删掉”。这个操作在技术上成本极低,一行DROP或者FILTER就完成了。但在OTD分析里,直接删除缺失“实际交付日期”的订单,会系统性地扭曲供应商绩效排序。
为什么?因为“实际交付日期”缺失这件事本身,往往和供应商的交付表现高度相关。根据我在项目中抽样分析过的数据,实际交付日期缺失的订单中,约有62%是已经严重逾期的订单。采购员或者供应商没有及时录入交付日期,本身就说明这条订单链条出了问题。你把这些订单全删了,剩下的大多是正常订单,OTD自然就“好看”了。
正确的做法不在技术,而在业务判断。我在项目里使用的策略是:

很多人做去重的时候只看“订单号+行项目号”有没有完全重复的行,这没问题。但还有另一种更难发现的重复:同一个物理订单在不同系统里有一条命不同的记录。
比如ERP里有一个采购订单PO20240101,WMS对应的是一个收货单GRN20240101A。但因为这个订单分了两批到货,WMS系统里自动拆成了GRN20240101A-1和GRN20240101A-2两条记录。你在BI平台做数据关联的时候,如果不理解这个拆分逻辑,可能会在ERP侧和WMS侧统计出不同的订单总数。
我在项目里解决这个问题的做法是:在清洗阶段定义“关联颗粒度”。不是所有的数据源都可以按订单号1:1关联的。如果收货端有拆分逻辑,那就必须在收货明细层面做聚合,再回到订单层面做关联。这个规则不清洗好,OTD的分子分母都对不上。
这个误区比较隐蔽,需要有一定项目经验才能发现。OTD=按时交付的订单数/总订单数,其中“按时”的基准就是承诺交付日期。但问题是,这个承诺交付日期在系统里可能已经被反复修改过了。
前面讲了季度末人为修改的例子。还有一种更普遍的情况:采购和供应商来回沟通,系统里会记录多个版本的承诺日期。采购在SAP里第一次下单填了一个日期,供应商说做不到,采购手动改一次;供应商又说物流安排不过来,再改一次。到最后,系统里保留的是最晚的、最容易完成的那个日期。
以这个被反复协商后的日期作为计算OTD的基准,对按时交付的定义当然就宽松得多。
我的做法是在项目里建立“首次承诺交付日期”和“最终承诺交付日期”双口径,前者按原始承诺衡量供应商履约能力,后者按协商后的结果衡量需求匹配度。这个设计在BI平台里只需要在ETL环节多拉一张历史快照表就能实现,但业务价值极高。

这是我早期犯过的错误。刚开始做OTD分析的时候,为了方便直接用了ERP里的“发货过账日期”作为实际交付日期。因为那个字段最全、格式最规整。但后来发现了一个严重偏差:
有一家供应商地处偏远,从发货到签收平均需要5天。用发货日算,它的准时交付率是88%;用客户签收日算,只有43%。差了一半。这意味着如果你只看“发货日期”,你完全看不清物流端的问题,而这恰恰是客户体验最直接的环节。
正确的做法是:在数据清洗阶段明确“交付节点锚定”。要业务的规则确定,到底是“货到客户手里”还是“货离开供应商仓库”算交付。不同品类、不同合同条款下的定义可能不一样。清洗的时候不能图省事取一个标准字段。
下面这套框架是我在五个以上供应链BI项目里反复打磨出来的,现在已经成了我带团队做OTD分析的标准流程。不是理论推演,是实战沉淀。
这是清洗的第一关,也是效率最高的筛选层。任何违反时间先后顺序的数据都应该被标记出来,而不是直接删除。
具体要校验的时间顺序关系包括:
我建议在BI平台的ETL环节单独创建一个“时序异常标记表”,把违反任一条规则的订单都打上标签,但不要在执行层直接丢弃。这些异常数据往往指向更深层的业务问题,比如采购事后补单、系统时间不同步、或者前面说的人为修改。

这一层是常规操作,但要注意顺序,必须先做完时序校验再做完整性校验。因为如果时序有问题,你填充默认值可能会引入新的逻辑错误。
完整性校验的关键字段清单:
有一个被很多人忽视的细节:日期格式的统一不能放在BI平台的展示层,必须在清洗层完成。不同的源系统可能返回YYYY-MM-DD、DD/MM/YYYY、或者时间戳格式。如果在展示层才转换,排序和计算都可能出错。清洗层的标准化是唯一正确的做法。
这一层是拉开专业分析师和普通BI开发人员差距的地方。业务规则校验要回答的问题是:这些数据在业务逻辑上是否站得住脚。
我常用的业务规则包括:
我在一个项目里就是通过业务规则校验发现了一个持续了8个月的采购合规问题,某个采购员负责的供应商,承诺交付日期的修改率是同岗同事的6倍以上,而且每次改动的方向都是往后推迟。这种问题如果不做业务规则校验,在报表层面只会看到一个“正常”的OTD数字。

这是最后一层校验,也是计算OTD之前最关键的步骤。ERP的订单数据、WMS的收货数据、供应商门户的反馈数据,三者之间必须做对账。
对账的关键指标有三个:
这一步的目的不是消灭所有差异,而是让差异显性化、让清洗过程可追溯。我在项目里会单独建一张“对账差异表”,记录每一次的差异原因、处理方式和责任人。这张表就是整个OTD分析的数据溯源链。
这是我在2023年下半年遇到的最有代表性的案例。客户是一家区域性云仓服务商,为三十多个品牌方提供仓配一体化服务。项目开始时,他们的月度供应商OTD报表显示94%的准时率。但我只做了三轮数据清洗,这个数字就降到了61%。
一上线我就发现问题,客户用的是仓库“上架完成时间”作为实际交付日期,而品牌方合同里写的是“客户签收时间”。仓库上架和最终客户签收之间,还有拣货、包装、快递配送三个环节。平均时间差是2.3天。
我只是把定义从“上架完成”改成“客户签收”,OTD就从94%降到了76%。18个百分点的差异源自同一个数据清洗决策。
这个客户的原始ETL脚本对“实际交付日期”为空的订单做了删除处理。我做了数据回溯,把过去6个月被删除的订单恢复出来,发现其中71%是逾期超过7天的严重超期订单。
这批订单被补回统计后,OTD从76%进一步降到了67%。又掉了9个百分点。
最后一轮,我追溯了每个供应商的承诺日期修改记录,把OTD从“最终承诺”口径切换到了“首次承诺”口径。结果发现有三家供应商在首次承诺日期下的准时率不到40%,但在多次修改后的最终承诺日期下能达到85%以上。
这轮修正让整体OTD从67%降到了61%。

这个案例给客户的冲击非常大。94%和61%之间不是数据质量的差异,而是两种完全不同的业务结论。前者的结论是“供应商表现优秀”,后者的结论是“供应链交付存在严重问题,需要系统性整改”。数据清洗不是把数据弄干净,而是在决定你看到什么样的业务真相。
没有一种清洗策略能适配所有供应链场景。我在不同类型的项目里总结了三套模式,分别对应三种典型业务形态。
这种场景的特点是SKU相对固定、订单量大但单笔金额不高、供应商关系稳定。典型的行业包括快消品、标准件制造。
清洗策略侧重:效率优先
取舍解释:在这个场景下单笔订单的影响权重很低,追求批量处理效率比追求单笔精准度更有价值。你不需要为一个1%的缺失率去做人工追溯,成本不划算。
这种场景常见于工业零部件、定制化包装材料等领域。订单量不大,但每笔订单的物料规格可能都不一样,而且经常涉及图纸确认、样品确认等前置环节。
清洗策略侧重:精准可控
取舍解释:这种场景下单笔订单影响大,一个关键物料的交付延期可能导致整条生产线停线。清洗效率可以让步于数据准确性。我做过一个精密轴承的案子,全年只有200多笔订单,每笔都做了人工校验。
这个场景的特点是数据来源极其分散,同一个品牌可能在淘宝、京东、拼多多、抖音小店都有店铺,每个平台的订单格式、交付时效要求都不一样。
清洗策略侧重:多维度兼容

数据清洗完成后,大多数人的做法是直接进入报表制作。但根据我的经验,清洗后不做校验,相当于做手术不检查伤口。下面是我在项目中固定的三个校验动作。
清洗前后,某些关键总量指标应该保持合理的变化范围。如果变化过大且没有合理解释,说明清洗规则有问题。
监控指标包括:
这是更细腻的校验方式。清洗前后,关键指标的分布形态应该基本一致。如果分布形态发生剧烈变化,比如清洗后交付周期突然变得非常集中、标准差大幅缩小,说明你可能把异常值过度清洗了。
我常用的分布校验指标:

最后一个校验动作最简单也最容易被忽略:把清洗后的关键数字拿给业务人员看,问他们“这个数字符合你的业务直觉吗”。
BI分析师很容易陷入数据逻辑的自洽,但忘记了数据最终要服务于业务判断。如果一个做了五年采购的人告诉你“这个供应商不可能有95%的准时率”,你与其在数据层面争论,不如去查这个供应商的清洗前后数据发生了什么变化。
我在项目里会固定安排一次“业务合理性评审”,邀请采购、仓储、质量部门的负责人一起看清洗后的OTD报表。很多时候他们在看报表的5分钟内就能发现数据问题,比分析脚本跑一天还有效。
最后这一部分是我认为最能体现专业度的实践。大多数团队的数据清洗是一个“黑盒”,数据进去、结果出来,中间发生了什么没人知道。三个月后再来看同样的OTD报表,谁也解释不清楚为什么数字变了。
我的标准做法是在BI平台的ETL节点里嵌入一套清洗日志机制,记录每一次清洗操作的元数据。
清洗日志的必记字段:
| 字段 | 说明 | 示例 |
|---|---|---|
| 清洗批次ID | 唯一标识每次清洗任务 | CLN-2024-03-15-001 |
| 清洗操作类型 | 删除/填充/修改/标记 | 填充 |
| 影响的数据范围 | 涉及的行数、字段名、筛选条件 | 实际交付日期为空, 影响387行 |
| 清洗规则 | 使用的填充值、删除条件 | 用承诺交付日期+7天填充 |
| 清洗原因 | 业务层面的说明 | 订单金额低于1万,且缺失交付日期,保守标记为逾期7天 |
| 操作人 | 谁执行的(或哪个脚本) | ETL_JOB_OTD_CLEAN |
| 操作时间 | 精确到分钟 | 2024-03-15 14:32:00 |
这套日志带来的价值远超你的想象。当三个月后财务部门质疑“为什么这个月的OTD比上个月低了15个百分点”,你可以直接调出清洗日志,精确到每一次操作、每一行数据的变动,解释清楚变化是由于清洗规则调整还是业务数据本身发生了变化。可追溯性,是专业数据清洗和非专业操作之间最本质的区别。
回到这篇文章标题里的“关键步骤”。我不打算在这个结尾把它总结成第一步干什么、第二步干什么的清单,那不是我的风格。真正关键的步骤只有一个思维转变:从“技术清洗”转向“业务翻译”。
你能把OTD清洗出什么结果,取决于你把“准时交付”翻译成了什么样的数据规则。翻译得越贴近业务真相,OTD数字就越有管理价值。翻译得越讨好报表阅读者,OTD数字就越好看但越没用。
如果你正在做OTD数据分析,我建议的下一步行动是:先放下清洗脚本,去找采购、仓储、物流三个部门的负责人各聊半小时。问他们一个问题,“在你的理解里,什么样的订单算准时交付”。你会惊讶地发现,三个人的回答可能完全不一样。而数据清洗的第一步,就是把这三个不同的定义,翻译成一套大家都认可的数据规则。
这一步不跑通,后面所有的BI报表都只是在输出漂亮的数字。
我最近在做供应链BI的OTD报表,发现不同部门算出来的准时率经常差好几个点。采购部用发货日期,仓库用签收日期,到底该用哪个作为‘实际交付’?数据清洗第一步到底是去重还是先统一时间定义?这个锚点不明确,后面清洗做得再干净是不是也白搭?
我在辅导一家电子制造企业时,发现他们的OTD报表在月初和月底能差15个百分点。根源就在于他们系统中‘实际交付日期’字段混用了发货出库时间和客户签收时间。采购部为了冲业绩,默认以发货时间为准;而仓库考核KPI却用签收时间。这导致同一订单在不同部门报表里呈现不同准时状态。
数据清洗的第一步绝不该是去重或统一格式,而应该是业务层面统一‘交付’的时间锚点。通常,把客户签收或仓库入库时间作为‘实际交付’更贴近真实服务水平。但也要考虑业务场景:如果客户验收周期很长(如大型设备),可以折中用‘仓库发货+物流签收平均时长’估算。
我建议的做法是:先与业务方开会确定一个唯一的‘交付事件’(如仓库确认出库后系统自动触发的时间戳),并在数据清洗规则中强制转换所有来源数据到这个锚点。这样后续的缺失值处理、异常值校验才有意义。否则,即使清洗掉重复项,算出的准时率也是虚假的。根据我的项目经验,这一步统一能消除至少5-10%的报表偏差。”
我在清洗供应商交付数据时遇到很多空白‘实际交付日期’,有些订单明明已经到货了但系统没录时间。同事说直接删除这些行,但我担心会丢掉重要信息,尤其是供应商交付波动大的月份。有没有更科学的办法?不同处理方式对最终准时率的影响到底有多大?
直接删除缺失‘实际交付日期’的订单行是最常见但也是最危险的做法。我见过一家快消企业,因为删除导致某供应商的准时率从82%虚标到95%,后来审计才发现那批被删除的订单全是逾期交付的极端案例。缺失的‘实际交付日期’其实是一个业务决策信号。我总结出三种处理策略及其业务影响:策略一:标记为逾期(最保守)。
将所有缺失视为未交付,适用于供应商逾期率高的高风险品类。这种策略会拉低准时率,但能暴露真实问题。策略二:用系统最晚交付时间填充(平衡)。如果该订单在WMS中有最后一次扫描记录(如出库时间),但客户签收未录,可以用出库时间+该供应商平均物流时长估算一个虚拟签收时间。
这种策略适用于数据录入习惯差的供应商,能部分还原真实情况。策略三:直接删除(风险大)。仅适用于缺失率极低(<5%)且能确认缺失完全随机的情况。
我在一个项目里做过对比表格:处理策略 | 准时率结果 | 数据量损失 | 业务建议标记为逾期 | 84.2% | 0% | 高风险物料正向激励填充法 | 89.7% | 0% | 常规供应商直接删除 | 92.3% | 8%损失 | 不推荐我的建议是:优先用策略二(填充法),并建立数据清洗日志记录每笔填充的算法和原始状态。
如果缺失率超过10%,要反向推动业务系统增加‘强制录入’的校验规则,从源头治理。”
最近我发现一家长期优秀的供应商准时率突然从98%掉到85%,但仔细看他们的交付记录,发现很多订单的‘实际交付日期’都被改成了和‘承诺日期’同一天,而仓库入库时间却显示晚了好几天。这种数据造假在BI平台里能自动识别吗?除了肉眼查,有没有系统化的清洗规则能揪出来?
这是我实战中遇到的最隐蔽也最让管理者头疼的问题。供应商为了保住大客户资格,可能通过修改系统时间戳或拆分订单来‘制造’准时。我总结过三种典型的作弊模式:第一,时间戳篡改,将实际交付日期修改为与承诺日期一致。第二,订单拆分,将一笔大额逾期订单拆分成多笔小额订单,其中一笔按时,其余后续补录。
第三,状态提前,系统状态已标记‘已交付’,但物流单号未更新。我的识别方法是建立‘二次校验’规则:规则一:计算承诺日期与实际交付日期的差值,但同时也计算实际发货日期(或仓库出库日期)与承诺日期的差值。如果前者为0而后者为正数(如发货晚于承诺),则标记为‘可疑准时’。
规则二:同一供应商在同一周内订单数量激增且平均金额骤降,可能是拆分行为。规则三:关联物流单号追踪,如果系统显示已交付但物流最后扫描时间晚于承诺日,也标记为异常。在BI平台中,我通常会创建一张‘清洗异常表’,把这些可疑记录单独输出,让采购进行人工复核。
我在一个案例中,通过这套规则发现一家供应商有30%的准时订单其实是‘伪准时’,该供应商实际准时率仅62%,远低于报表显示的95%。所以,建议在数据清洗流程中加入至少三个跨字段的交叉逻辑校验,而不是仅依赖单一‘实际交付日期’字段。”
我每次做OTD分析都花很多精力清洗数据,但下个月再看报表时,准时率又变了,我搞不清是因为业务变化了还是清洗规则变了。团队换人后,之前怎么处理的缺失值完全查不到记录。是不是应该记录下每次清洗的操作?这个清洗日志具体该怎么建,在BI平台里能实现吗?
我见过太多团队花80%时间做清洗,但从不记录清洗过程。结果就是BI报表成了‘黑箱’,指标波动了,没人能说清是业务波动还是清洗规则调整导致的。我自己在三个项目中强制推行了数据清洗日志,效果显著。
清洗日志至少要记录四个维度:时间戳(操作时间)、清洗规则(如‘删除实际交付日期为空的订单’)、影响数据量(如删除230行)、操作人及原因(如‘因ERP升级导致字段缺失’)。在九数云或FineBI这类平台中,可以通过‘ETL日志表’或‘清洗流程快照’实现半自动化。
具体做法:每次运行数据清洗作业时,自动生成一个结果表,记录原始行数、过滤后行数、异常值处理次数等统计量,并用一个固定模板保存到项目文件夹中。这样一个月后回看,就能定位是哪次清洗操作导致了准时率从90%降到88%,原来是调整了缺失值处理策略。
我在这分享一个案例:某物流企业曾因清洗人员误将‘发货日期为空’的订单全部删除,导致准时率虚高,但客户投诉飙升。有了清洗日志后,他们3分钟内就找到了元凶并恢复了数据。因此我强烈建议:在BI平台内建立‘数据清洗快照’机制,每次清洗前保存原始数据集快照,清洗后生成清洗记录。
这不仅提升报表可信度,也是数据治理审计的基石。建议将清洗日志作为BI分析流程的标准环节固化下来。”


读者评论
作为供应链数据分析师,文中提到的“发货日替代交付日”的坑我踩过无数次。用发货日算OTD,偏远地区供应商表现虚高,实际客户体验极差。文章提醒要先和业务定义“交付”节点,清洗时不能图省事取统一字段,这才是专业做法,比单纯教技术步骤有用得多。
供应商准时交付率的报表经常和实际体验对不上,文章点出了根本原因:数据清洗本质是翻译业务规则,不是打扫卫生。尤其是“承诺交付日期被修改”那段,季度末批量修改导致OTD从72%变94%,这种人为操作在BI里很难自动发现,建议建双口径清洗。专业且接地气。
我是BI平台用户,以前做OTD清洗默认删缺失值,看了文章才意识到问题:缺失往往和逾期正相关,全删了OTD自然好看。文中按订单金额分级处理(高价值人工确认、中等保守填充)的策略实操性强,避免了系统偏差。这种具体案例比通用教程有价值。
文中“四层校验框架”很有启发,特别是时序逻辑校验和字段完整性校验的顺序。之前我总把格式校验放前面,结果填充默认值反而制造了新错误。建议先做时序校验再填充,这个实践要点很多教程没提。整体内容有项目数据支撑,比纯理论干货扎实。