5.9 KiB
5.9 KiB
没有首次扫描时间的包裹处理逻辑 - 说明文档
更新日期: 2026-05-16
主题: 边界情况处理 - 当包裹没有扫描记录时
状态: ✅ 编译通过
问题说明
场景:如果一个交接单标签率达到了80%,但其中有些包裹从未被扫描过(即没有首次扫描时间),应该如何处理?
当前SQL逻辑:
WHERE l.Label IS NOT NULL AND l.Label != ''
AND (
SELECT MIN(ls.CreatedAt)
FROM label_scan_history ls
WHERE ls.NeutralWaybillNumber = l.NeutralWaybillNumber
) > l.LabelRetrievedAt
问题分析:
- 当
label_scan_history中没有记录时,MIN(ls.CreatedAt)返回 NULL NULL > l.LabelRetrievedAt的比较结果是 NULL(未知)- 在 CASE WHEN 中,NULL 被视为 FALSE
- 这些包裹不被计入"高标签率"的分子
- 导致整个交接单的冻结标签率会偏低
处理方案
方案选择
选择:当没有首次扫描时间时,按低标签率处理
原因
-
业务逻辑:
- 如果一个包裹从未被扫描,说明它还未开始作业
- 标签的作用是在作业过程中发挥作用
- 如果作业未开始,标签的可用性无法判断
- 保守处理:默认认为标签在此时不可用
-
风险规避:
- 避免高估标签率
- 确保考核时间的合理性
-
数据质量:
- 如果包裹从未被扫描,可能说明:
- 包裹尚未送达仓库
- 包裹信息不完整
- 系统记录有缺失
- 如果包裹从未被扫描,可能说明:
SQL实现细节
当前逻辑:
冻结标签率 = (最早扫描时间 > 标签推送时间的包裹数) / 总包裹数
处理规则:
IF 最早扫描时间 IS NOT NULL THEN
IF 最早扫描时间 > 标签推送时间 THEN
→ 计入高标签率分子
ELSE
→ 不计入高标签率分子
END IF
ELSE
-- 没有扫描时间
→ 默认不计入高标签率分子(按低标签率处理)
END IF
具体场景示例
场景1:交接单中的所有包裹都没有扫描记录
交接单A:
├─ 总包裹数:100
├─ 有标签的包裹:80
├─ 扫描过的包裹:0(全部未扫描)
├─ 最早扫描时间:NULL
└─ 冻结标签率计算:
分子 = 0(因为没有满足"最早扫描时间 > 标签推送时间"的包裹)
分母 = 100
冻结标签率 = 0%(低标签率)
考核规则:按低标签率处理(完成即达标)
场景2:交接单中的部分包裹没有扫描记录
交接单B:
├─ 总包裹数:100
├─ 有标签的包裹:90
├─ 扫描过的包裹:70
│ ├─ 其中:标签推送时间 < 扫描时间的包裹:60
│ └─ 其中:标签推送时间 >= 扫描时间的包裹:10
└─ 未扫描的包裹:30
└─ 这30个包裹不计入高标签率分子
冻结标签率计算:
分子 = 60(符合"最早扫描时间 > 标签推送时间"的包裹)
分母 = 100
冻结标签率 = 60%(低标签率)
考核规则:按低标签率处理(完成即达标)
场景3:交接单中大部分包裹有扫描记录,少数没有
交接单C:
├─ 总包裹数:100
├─ 有标签的包裹:95
├─ 扫描过的包裹:99
│ ├─ 其中:最早扫描时间 > 标签推送时间的包裹:85
│ └─ 其中:最早扫描时间 <= 标签推送时间的包裹:14
└─ 未扫描的包裹:1
└─ 这1个包裹不计入高标签率分子
冻结标签率计算:
分子 = 85(满足条件的包裹)
分母 = 100
冻结标签率 = 85%(高标签率)
考核规则:按高标签率处理(16点分段)
对各个CTE的影响
InterchangeUnitLabelRates
计算逻辑:
labeled_requests = COUNT(DISTINCT CASE
WHEN l.Label IS NOT NULL
AND MIN(ls.CreatedAt) > l.LabelRetrievedAt
THEN l.Id
END)
对没有扫描时间的包裹:
- ✅ 自动不计入 labeled_requests
- ✅ 因此不会虚高冻结标签率
DailyHighLabelRateShould
逻辑:根据 label_rate_percent >= 80 判断
对影响:
- 如果因为没有扫描记录导致冻结标签率 < 80%
- 该交接单会被分类到"低标签率"
- 所有包裹都按低标签率规则处理
DailyLowLabelRateShould
逻辑:根据 label_rate_percent < 80 判断
对影响:
- 包含没有扫描记录的交接单
- 这些包裹按完成即达标处理
- 符合保守处理的原则
数据质量检查建议
建议1:监控未扫描的包裹
在报表中补充一个指标:
未扫描包裹数 = COUNT(DISTINCT 订单) WHERE 首次扫描时间 IS NULL
未扫描率 = 未扫描包裹数 / 总包裹数
建议2:定期检查异常
IF 未扫描率 > 某个阈值(例如5%) THEN
→ 报警,检查系统是否有问题
→ 检查数据导入是否完整
END IF
建议3:与现场对账
定期与现场对账,确认:
- 是否真的有包裹未被扫描
- 还是系统记录有缺失
总结
当前处理方式
没有首次扫描时间
↓
不被计入高标签率分子
↓
冻结标签率偏低(或保持原来的水平)
↓
按低标签率规则处理(完成即达标)
优点
- ✅ 安全保守:避免高估标签率
- ✅ 符合业务逻辑:作业未开始时,标签不可用
- ✅ 自动处理:无需特殊编码,SQL逻辑自动应对
- ✅ 考核公平:低标签率的包裹按更宽松的规则考核
可能的改进
如果后续发现有频繁的未扫描现象,可以:
- 加强数据导入的完整性检查
- 增加数据质量监控指标
- 与现场沟通,了解根本原因
- 根据实际情况调整处理策略
编译状态
✅ 编译成功 (exit code 0)
- SQL逻辑已加注释,明确说明处理方式
- 无编译错误
- 业务逻辑清晰