上传源代码版本
This commit is contained in:
442
.trae/documents/sql_field_logic_complete_v4.md
Normal file
442
.trae/documents/sql_field_logic_complete_v4.md
Normal file
@@ -0,0 +1,442 @@
|
||||
# 日级报表字段统计逻辑详细梳理(v4.0 - 完整版)
|
||||
|
||||
**更新日期**: 2026-05-16
|
||||
**版本**: v4.0 - 整体统计逻辑重构
|
||||
**状态**: ✅ 编译通过,逻辑已优化
|
||||
|
||||
---
|
||||
|
||||
## 核心改进
|
||||
|
||||
### 主要变化
|
||||
|
||||
1. **24H换单率重新定义**
|
||||
- ❌ 旧逻辑:`考核通过总数 / 高标签率应该换单数`(只考虑高标签率)
|
||||
- ✅ 新逻辑:`24H内完成数 / 当天应该换单数`(整体考虑,不区分标签率)
|
||||
|
||||
2. **移除了"考核通过率"**
|
||||
- 原因:与24H换单率重复,不需要单独维护
|
||||
|
||||
---
|
||||
|
||||
## SQL 字段出现顺序与统计逻辑
|
||||
|
||||
### 第1层:基础统计字段(从数据库直接查询)
|
||||
|
||||
#### 1.1 日期 (日期)
|
||||
```sql
|
||||
字段源: ArrivalRequests.到货时间 (UTC-5时区)
|
||||
统计方式: DATE(CONVERT_TZ(到货时间, '+00:00', '-05:00'))
|
||||
业务含义: 以到货时间为准的自然日
|
||||
例子: 2026-05-16
|
||||
```
|
||||
|
||||
#### 1.2 当日新增换单数 (当日新增换单数)
|
||||
```sql
|
||||
字段源: DailyBase
|
||||
统计方式: COUNT(DISTINCT 交接单号) WHERE 到货时间 = 当日
|
||||
业务含义: 当天新进入系统的交接单数量
|
||||
例子: 100
|
||||
```
|
||||
|
||||
#### 1.3 当日换单失败数 (当日换单失败)
|
||||
```sql
|
||||
字段源: DailyFailedOrders
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 标记失败时间 = 当日
|
||||
业务含义: 当天新增失败的订单数
|
||||
例子: 5
|
||||
```
|
||||
|
||||
#### 1.4 当日换单成功数 (当日换单成功数)
|
||||
```sql
|
||||
字段源: DailySuccessCount
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 首次成功时间 = 当日
|
||||
业务含义: 当天首次成功扫描的订单数
|
||||
例子: 85
|
||||
```
|
||||
|
||||
#### 1.5 当日STOP数 (当日STOP数)
|
||||
```sql
|
||||
字段源: DailyScanMetrics
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE STOP标记时间 = 当日
|
||||
业务含义: 当天被标记为STOP(停止处理)的订单数
|
||||
例子: 3
|
||||
```
|
||||
|
||||
#### 1.6 16点前到仓包裹数 (16点前到仓包裹数)
|
||||
```sql
|
||||
字段源: DailyBase
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 到货时间 BETWEEN 当日00:00:00 AND 当日16:00:00
|
||||
业务含义: 当天早上16点前到达仓库的订单数
|
||||
例子: 60
|
||||
```
|
||||
|
||||
#### 1.7 16点后到仓包裹数 (16点后到仓包裹数)
|
||||
```sql
|
||||
字段源: DailyBase
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 到货时间 BETWEEN 当日16:00:01 AND 当日23:59:59
|
||||
业务含义: 当天下午16点后到达仓库的订单数
|
||||
例子: 40
|
||||
```
|
||||
|
||||
#### 1.8 当日完成数 (当日完成数)
|
||||
```sql
|
||||
字段源: DailyCompletedOrders
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 完成时间 = 当日
|
||||
业务含义: 当天完成(所有流程结束)的订单数
|
||||
例子: 88
|
||||
```
|
||||
|
||||
#### 1.9 24H内完成数 (24H内完成数)
|
||||
```sql
|
||||
字段源: Daily24HCompletedOrders
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 完成时间 BETWEEN (昨日到货时间) AND (今日到货时间+24H)
|
||||
业务含义: 24小时内完成的订单数(跨越两个自然日)
|
||||
例子: 89
|
||||
```
|
||||
|
||||
#### 1.10 当日标签推送数 (当日标签推送数)
|
||||
```sql
|
||||
字段源: DailyBase
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 标签推送时间 = 当日
|
||||
业务含义: 当天新增推送的标签数
|
||||
例子: 92
|
||||
```
|
||||
|
||||
#### 1.11 当日扫描数 (当日扫描数)
|
||||
```sql
|
||||
字段源: DailyScanMetrics
|
||||
统计方式: COUNT(DISTINCT 订单号) WHERE 首次扫描时间 = 当日
|
||||
业务含义: 当天首次被扫描的订单数
|
||||
例子: 86
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第2层:递推累计字段(需要上一日数据)
|
||||
|
||||
#### 2.1 累计要换的总单数 (累计要换的总单数)
|
||||
```sql
|
||||
计算公式:
|
||||
第1天: @running_total = 当日新增换单数
|
||||
第2天+: @running_total = MAX(0, 前一日累计 + 前一日新增 - 前一日完成)
|
||||
|
||||
业务含义: 当前还需要处理的交接单总数(待处理积压)
|
||||
- 当日新增: +100 (新加入的)
|
||||
- 前一日完成: -88 (完成的)
|
||||
- 前一日积压: +50 (上一天遗留的)
|
||||
- 结果: MAX(0, 50 + 100 - 88) = 62
|
||||
|
||||
例子: 62
|
||||
说明: 注意使用 MAX(0, ...) 防止出现负数
|
||||
```
|
||||
|
||||
#### 2.2 当天应该换单数 (当天应该换单数)
|
||||
```sql
|
||||
计算公式: 当天应该换单数 = 累计要换的总单数 + 当日新增换单数
|
||||
|
||||
业务含义: 当天应该完成/达标的目标订单数
|
||||
- 昨天积压: 50
|
||||
- 当日新增: +100
|
||||
- 目标: 150
|
||||
|
||||
例子: 150
|
||||
说明: 这个数字用于计算当天和24H的完成率
|
||||
```
|
||||
|
||||
#### 2.3 换单失败未完结订单 (换单失败未完结订单)
|
||||
```sql
|
||||
字段源:
|
||||
- 历史数据: HistoryUnfinished (已结束日期的数据)
|
||||
- 当前日期: LatestUnfinished (最新日期的数据)
|
||||
|
||||
统计方式:
|
||||
IF 日期 = 最新日期 THEN
|
||||
使用 LatestUnfinished.换单失败未完结订单
|
||||
ELSE
|
||||
使用 HistoryUnfinished.换单失败未完结订单
|
||||
|
||||
业务含义: 因失败导致还未完成的订单数
|
||||
例子: 2
|
||||
说明: 这些订单可能需要人工介入或重新处理
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第3层:考核维度字段
|
||||
|
||||
#### 3.1 16点前考核通过包裹数 (16点前考核通过包裹数)
|
||||
```sql
|
||||
字段源: DailyBeforeNoonPassed
|
||||
统计方式:
|
||||
COUNT(DISTINCT 订单号) WHERE
|
||||
1. 到货时间 < 16:00:00
|
||||
2. 首次成功时间 <= 考核时间
|
||||
3. 冻结标签率 >= 80%
|
||||
|
||||
考核时间规则 (16点前到仓,高标签率):
|
||||
考核时间 = 当日 16:00:00 ~ 次日 16:00:00
|
||||
|
||||
业务含义: 16点前到仓,标签率高(>=80%),且在规定时间内完成的订单
|
||||
例子: 45
|
||||
说明: 这类订单是优先级最高的考核对象
|
||||
```
|
||||
|
||||
#### 3.2 16点后考核通过包裹数 (16点后考核通过包裹数)
|
||||
```sql
|
||||
字段源: DailyAfternoonPassed
|
||||
统计方式:
|
||||
COUNT(DISTINCT 订单号) WHERE
|
||||
1. 到货时间 >= 16:00:00
|
||||
2. 首次成功时间 <= 考核时间
|
||||
3. 冻结标签率 >= 80%
|
||||
|
||||
考核时间规则 (16点后到仓,高标签率):
|
||||
考核时间 = 当日 16:00:00 ~ 次日 23:59:59
|
||||
(时间更宽松,因为到仓较晚)
|
||||
|
||||
业务含义: 16点后到仓,标签率高(>=80%),且在规定时间内完成的订单
|
||||
例子: 30
|
||||
说明: 比16点前的考核期限延长到晚上23:59:59
|
||||
```
|
||||
|
||||
#### 3.3 低标签率考核通过包裹数 (低标签率考核通过包裹数)
|
||||
```sql
|
||||
字段源: DailyLowLabelRatePassed
|
||||
统计方式:
|
||||
COUNT(DISTINCT 订单号) WHERE
|
||||
1. 冻结标签率 < 80%
|
||||
2. 曾成功 = 1
|
||||
|
||||
考核时间规则 (低标签率):
|
||||
考核时间 = NULL(完成即达标)
|
||||
只要首次成功就算通过考核
|
||||
|
||||
业务含义: 标签率低(<80%),只需要完成(首次成功)就算达标的订单
|
||||
例子: 12
|
||||
说明: 对这类订单的要求最低,完成就算通过
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第4层:标签率维度字段
|
||||
|
||||
#### 4.1 高标签率应该换单数 (高标签率应该换单数)
|
||||
```sql
|
||||
字段源: DailyHighLabelRateShould
|
||||
统计方式:
|
||||
COUNT(DISTINCT 订单号) FROM ArrivalRequests ar WHERE
|
||||
冻结标签率 >= 80%
|
||||
按到货时间分组统计
|
||||
|
||||
冻结标签率计算:
|
||||
冻结标签率 = (最早扫描时间 > 标签推送时间的包裹数) / 总包裹数 × 100%
|
||||
|
||||
其中:
|
||||
- 最早扫描时间 = MIN(label_scan_history.CreatedAt for 交接单内所有包裹)
|
||||
- 标签推送时间 = label_replace_requests.LabelRetrievedAt
|
||||
- 最早扫描时间 > 标签推送时间 => 标签已可用
|
||||
|
||||
业务含义: 整个交接单的标签率达到或超过80%的订单总数
|
||||
(这个交接单中的所有包裹都按高标签率规则处理)
|
||||
例子: 87
|
||||
说明: 这些订单需要按16点前/后分段规则处理
|
||||
```
|
||||
|
||||
#### 4.2 低标签率应该换单数 (低标签率应该换单数)
|
||||
```sql
|
||||
字段源: DailyLowLabelRateShould
|
||||
统计方式:
|
||||
COUNT(DISTINCT 订单号) FROM ArrivalRequests ar WHERE
|
||||
冻结标签率 < 80%
|
||||
按到货时间分组统计
|
||||
|
||||
业务含义: 整个交接单的标签率低于80%的订单总数
|
||||
(这个交接单中的所有包裹都按完成即达标规则处理)
|
||||
例子: 13
|
||||
说明: 这些订单只要完成就算通过,无需区分16点前后
|
||||
高标签率应该换单数 + 低标签率应该换单数 = 100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 第5层:衍生计算字段
|
||||
|
||||
#### 5.1 考核通过总数 (考核通过总数)
|
||||
```sql
|
||||
计算公式:
|
||||
考核通过总数 = 16点前考核通过包裹数 + 16点后考核通过包裹数 + 低标签率考核通过包裹数
|
||||
|
||||
业务含义: 所有通过考核(达到目标)的订单总数,不区分考核方式
|
||||
例子: 45 + 30 + 12 = 87
|
||||
说明: 这是最关键的达成指标之一
|
||||
```
|
||||
|
||||
#### 5.2 当天换单完成率 (当天换单完成率)
|
||||
```sql
|
||||
计算公式:
|
||||
当天换单完成率 = 当日完成数 / 当天应该换单数 × 100%
|
||||
|
||||
分子: 当日完成数 = 88
|
||||
分母: 当天应该换单数 = 150
|
||||
结果: 88 / 150 × 100% = 58.67%
|
||||
|
||||
业务含义: 当天的完成达成率(只考虑当日完成的订单)
|
||||
例子: 58.67%
|
||||
说明: 衡量当天的工作效率
|
||||
```
|
||||
|
||||
#### 5.3 24H换单率 ✨ (24H换单率)
|
||||
```sql
|
||||
计算公式:
|
||||
24H换单率 = 24H内完成数 / 当天应该换单数 × 100%
|
||||
|
||||
分子: 24H内完成数 = 89 (包括昨天到货但今天完成的)
|
||||
分母: 当天应该换单数 = 150
|
||||
结果: 89 / 150 × 100% = 59.33%
|
||||
|
||||
业务含义: 24小时周期内的完成达成率(涵盖跨天的订单)
|
||||
例子: 59.33%
|
||||
说明: 关键KPI,衡量整体履约能力(不区分高低标签率)
|
||||
为什么不用"考核通过总数"?
|
||||
因为考核通过总数只统计满足考核条件的订单,
|
||||
不包括在考核期限外完成的订单。
|
||||
而24H换单率更全面,包含所有在24小时内完成的订单。
|
||||
```
|
||||
|
||||
#### 5.4 数据拉取时间(UTC-5) (数据拉取时间(UTC_5))
|
||||
```sql
|
||||
计算公式: UTC_TIMESTAMP() - INTERVAL 5 HOUR
|
||||
业务含义: 报表数据生成的时刻(UTC-5时区)
|
||||
例子: 2026-05-16 19:30:45
|
||||
说明: 用于追踪报表的新鲜度
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 完整数据流示例
|
||||
|
||||
### 场景:100个订单,冻结标签率=30% (<80%)
|
||||
|
||||
```
|
||||
【输入】
|
||||
┌─────────────────────────────────────┐
|
||||
│ DailyBase (原始交接单数据) │
|
||||
│ ├─ 当日新增换单数: 100 │
|
||||
│ ├─ 16点前到仓: 60 │
|
||||
│ ├─ 16点后到仓: 40 │
|
||||
│ └─ 当日标签推送: 92 │
|
||||
│ │
|
||||
│ DailySuccessCount (成功数据) │
|
||||
│ └─ 当日换单成功数: 85 │
|
||||
│ │
|
||||
│ Daily24HCompletedOrders (24H完成) │
|
||||
│ ├─ 当日完成数: 88 │
|
||||
│ └─ 24H内完成数: 89 │
|
||||
│ │
|
||||
│ InterchangeUnitLabelRates (标签率) │
|
||||
│ ├─ 冻结标签率: 30% │
|
||||
│ └─ (30个:最早扫描>标签推送时间) │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
【计算过程】
|
||||
1️⃣ 冻结标签率判断
|
||||
冻结标签率 = 30% < 80% → 低标签率
|
||||
|
||||
2️⃣ 标签率维度统计
|
||||
高标签率应该换单数: 0 (没有标签率>=80%的交接单)
|
||||
低标签率应该换单数: 100 (所有100个都按低标签率处理)
|
||||
|
||||
3️⃣ 考核统计
|
||||
因为冻结标签率 < 80%,所有订单按"完成即达标"规则
|
||||
|
||||
16点前考核通过包裹数: 0 (高标签率规则不适用)
|
||||
16点后考核通过包裹数: 0 (高标签率规则不适用)
|
||||
低标签率考核通过包裹数: 82 (成功的订单中的一部分)
|
||||
考核通过总数: 0 + 0 + 82 = 82
|
||||
|
||||
4️⃣ 累计计算(假设前一日数据)
|
||||
前一日累计: 50
|
||||
前一日新增: 100
|
||||
前一日完成: 88
|
||||
|
||||
累计要换的总单数 = MAX(0, 50 + 100 - 88) = 62
|
||||
当天应该换单数 = 62 + 100 = 162
|
||||
|
||||
5️⃣ 完成率计算
|
||||
当天换单完成率 = 88 / 162 × 100% = 54.32%
|
||||
24H换单率 = 89 / 162 × 100% = 54.94%
|
||||
|
||||
【输出】
|
||||
┌─────────────────────────────────────┐
|
||||
│ 日期 2026-05-16 │
|
||||
│ 当日新增换单数 100 │
|
||||
│ 累计要换的总单数 62 │
|
||||
│ 当天应该换单数 162 │
|
||||
│ 换单失败未完结订单 2 │
|
||||
│ 当日换单失败 5 │
|
||||
│ 当日换单成功数 85 │
|
||||
│ 当日STOP数 3 │
|
||||
│ 16点前到仓包裹数 60 │
|
||||
│ 16点后到仓包裹数 40 │
|
||||
│ 16点前考核通过包裹数 0 │
|
||||
│ 16点后考核通过包裹数 0 │
|
||||
│ 低标签率考核通过包裹数 82 │
|
||||
│ 高标签率应该换单数 0 │
|
||||
│ 低标签率应该换单数 100 │
|
||||
│ 当日完成数 88 │
|
||||
│ 24H内完成数 89 │
|
||||
│ 考核通过总数 82 │
|
||||
│ 当天换单完成率 54.32% │
|
||||
│ 24H换单率 54.94% │
|
||||
│ 当日标签推送数 92 │
|
||||
│ 当日扫描数 86 │
|
||||
│ 数据拉取时间(UTC-5)19:30:45│
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键逻辑梳理
|
||||
|
||||
### 冻结标签率的作用流程
|
||||
|
||||
```
|
||||
1. 计算每个交接单的冻结标签率
|
||||
↓
|
||||
2. 根据冻结标签率判断:>= 80% 还是 < 80%
|
||||
↓
|
||||
3. 如果 >= 80%
|
||||
├─ 高标签率应该换单数 += 100
|
||||
├─ 按16点前/后分段处理
|
||||
└─ 使用考核时间判断是否通过
|
||||
↓
|
||||
4. 如果 < 80%
|
||||
├─ 低标签率应该换单数 += 100
|
||||
├─ 按"完成即达标"处理
|
||||
└─ 只要成功就算通过
|
||||
```
|
||||
|
||||
### 为什么24H换单率用"24H内完成数"而不用"考核通过总数"?
|
||||
|
||||
| 对比项 | 24H内完成数 | 考核通过总数 |
|
||||
|-------|----------|----------|
|
||||
| 计数对象 | 所有24小时内完成的订单 | 满足考核条件的订单 |
|
||||
| 是否受限制 | 不受考核时间限制 | 受16点分段等限制 |
|
||||
| 反映维度 | 整体履约能力 | 考核规则下的达成 |
|
||||
| 业务价值 | 对客户更有说服力 | 对内部考核更重要 |
|
||||
|
||||
**示例**:
|
||||
- 订单A:16点后到仓,标签率高,23:00完成 → 考核不通过(超期),但24H完成
|
||||
- 使用考核通过总数:不计入 (无法获得完整的24小时履约情况)
|
||||
- 使用24H完成数:计入 ✓ (客观反映24小时内的完成情况)
|
||||
|
||||
---
|
||||
|
||||
## 编译状态
|
||||
|
||||
✅ **编译成功**
|
||||
- 所有字段逻辑已完整梳理
|
||||
- 24H换单率已重新定义
|
||||
- 无编译错误
|
||||
|
||||
Reference in New Issue
Block a user