上传源代码版本
This commit is contained in:
246
.trae/documents/diagnose_24h_rate_formula_plan.md
Normal file
246
.trae/documents/diagnose_24h_rate_formula_plan.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# 24H换单率异常超高的根本原因诊断与修复计划(v2)
|
||||
|
||||
**问题**:修改后24H换单率仍然异常高(4745%、17924%、11193%、78075%)
|
||||
|
||||
**用户需求**:明确表述24小时换单率的分子和分母分别是什么
|
||||
|
||||
---
|
||||
|
||||
## 第1阶段:明确当前的计算定义
|
||||
|
||||
### 任务1:读取SQL中24H换单率的完整计算公式
|
||||
|
||||
**位置**:LabelReplaceRepository.cs 中的最终SELECT语句
|
||||
|
||||
**检查内容**:
|
||||
- [ ] 找到24H换单率的计算表达式
|
||||
- [ ] 确认分子是什么字段/表达式
|
||||
- [ ] 确认分母是什么字段/表达式
|
||||
- [ ] 看看是否有其他修饰(如乘以100)
|
||||
|
||||
**目的**:得到精确的公式:`24H换单率 = ? / ? × 100%`
|
||||
|
||||
### 任务2:逐个检查涉及的CTE
|
||||
|
||||
**需要检查的CTE**:
|
||||
1. [ ] DailyHighLabelRateAssessed(高标签率考核通过数)
|
||||
- 检查是否有重复统计
|
||||
- 检查UNION ALL是否导致了重复
|
||||
|
||||
2. [ ] DailyHighLabelRateShould(高标签率应该换单数)
|
||||
- 检查修改后的逻辑是否正确
|
||||
- 检查CONCAT是否导致了其他问题
|
||||
|
||||
3. [ ] DailyBeforeNoonPassed(16点前考核通过)
|
||||
- 检查是否有重复的包裹被计算
|
||||
|
||||
4. [ ] DailyAfternoonPassed(16点后考核通过)
|
||||
- 检查是否有重复的包裹被计算
|
||||
|
||||
### 任务3:用SQL直接查询各CTE的结果
|
||||
|
||||
**执行诊断查询**:
|
||||
```sql
|
||||
-- 查询某一天的数据分解
|
||||
SELECT '日期' AS 类型, 日期 AS 值, 0 AS 数量
|
||||
UNION ALL
|
||||
SELECT 'DailyBeforeNoonPassed', CAST(16点前考核通过包裹数 AS CHAR), 16点前考核通过包裹数
|
||||
UNION ALL
|
||||
SELECT 'DailyAfternoonPassed', CAST(16点后考核通过包裹数 AS CHAR), 16点后考核通过包裹数
|
||||
UNION ALL
|
||||
SELECT 'DailyHighLabelRateShould', CAST(高标签率应该换单数 AS CHAR), 高标签率应该换单数
|
||||
```
|
||||
|
||||
**目的**:看到每个数值,找出倍数关系
|
||||
|
||||
---
|
||||
|
||||
## 第2阶段:分析数值关系
|
||||
|
||||
### 任务4:倍数分析
|
||||
|
||||
**假设某一天的数据**:
|
||||
- 高标签率应该换单数 = 100
|
||||
- 16点前考核通过 = 200
|
||||
- 16点后考核通过 = 100
|
||||
- 高标签率考核通过数 = 200 + 100 = 300
|
||||
- 24H换单率 = 300 / 100 × 100% = 300%(已经异常)
|
||||
|
||||
**如果24H换单率 = 4745%**:
|
||||
- 可能是:4745 / 100 × 100% = 4745%
|
||||
- 那么分子 = 4745,分母 = 100
|
||||
- 这表示高标签率考核通过数 = 4745?或者计算中的乘法错误?
|
||||
|
||||
**检查点**:
|
||||
- [ ] 16点前考核通过包裹是否被多次计算
|
||||
- [ ] 16点后考核通过包裹是否被多次计算
|
||||
- [ ] 是否有UNION ALL导致的重复
|
||||
- [ ] 是否有JOIN导致的笛卡尔积
|
||||
|
||||
### 任务5:追踪单个包裹
|
||||
|
||||
**选择一个具体的包裹**:
|
||||
- [ ] 查询这个包裹在 DailyBeforeNoonPassed 中是否出现1次
|
||||
- [ ] 查询这个包裹在 DailyAfternoonPassed 中是否出现1次
|
||||
- [ ] 查询在 DailyHighLabelRateAssessed 中被计算了几次
|
||||
- [ ] 确定重复的位置
|
||||
|
||||
---
|
||||
|
||||
## 第3阶段:确定真正的问题
|
||||
|
||||
### 可能的原因
|
||||
|
||||
#### 原因A:DailyBeforeNoonPassed/DailyAfternoonPassed中有重复
|
||||
|
||||
**症状**:
|
||||
- 同一个包裹在 DailyBeforeNoonPassed 中被计算多次
|
||||
- 或者同一个包裹在 DailyAfternoonPassed 中被计算多次
|
||||
|
||||
**检查方式**:
|
||||
```sql
|
||||
SELECT 日期, COUNT(*) as 行数
|
||||
FROM DailyBeforeNoonPassed
|
||||
GROUP BY 日期
|
||||
-- 应该每天只有1条记录,如果有多条就是问题
|
||||
```
|
||||
|
||||
#### 原因B:DailyHighLabelRateAssessed中UNION ALL导致重复
|
||||
|
||||
**症状**:
|
||||
- DailyBeforeNoonPassed 和 DailyAfternoonPassed 的数据在 UNION ALL 后没有正确汇总
|
||||
- 或者 GROUP BY 日期后仍然有多行
|
||||
|
||||
**检查方式**:
|
||||
```sql
|
||||
SELECT 日期, COUNT(*) as 行数
|
||||
FROM DailyHighLabelRateAssessed
|
||||
GROUP BY 日期
|
||||
-- 应该每天只有1条记录
|
||||
```
|
||||
|
||||
#### 原因C:主SELECT中的JOIN导致笛卡尔积
|
||||
|
||||
**症状**:
|
||||
- 多个 LEFT JOIN 导致了行数增加
|
||||
- 例如:JOIN DailyHighLabelRateShould 和 JOIN DailyHighLabelRateAssessed 在同时时产生了交叉
|
||||
|
||||
**检查方式**:
|
||||
- 在主SELECT中加入 COUNT(*),看总记录数
|
||||
- 检查是否多于预期
|
||||
|
||||
#### 原因D:COUNT的方式问题
|
||||
|
||||
**症状**:
|
||||
- 在外层SELECT中没有正确处理聚合
|
||||
- 或者在JOIN后没有正确聚合
|
||||
|
||||
---
|
||||
|
||||
## 第4阶段:修复问题
|
||||
|
||||
### 修复策略(取决于根本原因)
|
||||
|
||||
#### 如果是原因A(DailyBeforeNoonPassed/DailyAfternoonPassed重复)
|
||||
|
||||
**修复方式**:
|
||||
- 检查这两个CTE的 GROUP BY 是否完整
|
||||
- 可能需要加入更多分组字段
|
||||
- 或者改成 SELECT DISTINCT
|
||||
|
||||
#### 如果是原因B(DailyHighLabelRateAssessed汇总错误)
|
||||
|
||||
**修复方式**:
|
||||
```sql
|
||||
-- 改为
|
||||
DailyHighLabelRateAssessed AS (
|
||||
SELECT
|
||||
日期,
|
||||
SUM(16点前考核通过包裹数) + SUM(16点后考核通过包裹数) AS 高标签率考核通过数
|
||||
FROM (
|
||||
SELECT DISTINCT 日期, 16点前考核通过包裹数, 0 AS 16点后考核通过包裹数
|
||||
FROM DailyBeforeNoonPassed
|
||||
UNION ALL
|
||||
SELECT DISTINCT 日期, 0 AS 16点前考核通过包裹数, 16点后考核通过包裹数
|
||||
FROM DailyAfternoonPassed
|
||||
) t
|
||||
GROUP BY 日期
|
||||
)
|
||||
```
|
||||
|
||||
#### 如果是原因C(JOIN笛卡尔积)
|
||||
|
||||
**修复方式**:
|
||||
- 在主SELECT中加 GROUP BY 日期
|
||||
- 或者改变JOIN的方式,让每个日期只有一条记录进入
|
||||
|
||||
#### 如果是原因D(COUNT方式问题)
|
||||
|
||||
**修复方式**:
|
||||
- 确保所有字段都被正确聚合
|
||||
- 如果有非聚合函数的字段,必须在 GROUP BY 中
|
||||
|
||||
---
|
||||
|
||||
## 第5阶段:编写清晰的24H换单率定义
|
||||
|
||||
### 任务:编写规范定义
|
||||
|
||||
**定义模板**:
|
||||
```
|
||||
24H换单率 的定义
|
||||
================
|
||||
|
||||
分子 = ___________(准确的字段名或计算表达式)
|
||||
= 来源CTE: ___________
|
||||
= 含义: ___________
|
||||
|
||||
分母 = ___________(准确的字段名或计算表达式)
|
||||
= 来源CTE: ___________
|
||||
= 含义: ___________
|
||||
|
||||
计算公式 = 分子 / 分母 × 100%
|
||||
|
||||
业务含义:
|
||||
```
|
||||
|
||||
**填写规则**:
|
||||
- [ ] 分子必须精确到SQL字段或表达式
|
||||
- [ ] 分母必须精确到SQL字段或表达式
|
||||
- [ ] 必须注明数据来源
|
||||
- [ ] 必须解释为什么这样定义
|
||||
|
||||
---
|
||||
|
||||
## 第6阶段:验证修复
|
||||
|
||||
### 任务:验证修复后的结果
|
||||
|
||||
**验证标准**:
|
||||
- [ ] 24H换单率 <= 100%
|
||||
- [ ] 分子 <= 分母
|
||||
- [ ] 每个日期的数据合理(对比业务预期)
|
||||
- [ ] 能够手工验证某一天的计算结果
|
||||
|
||||
### 测试用例
|
||||
|
||||
**准备简单数据**:
|
||||
- 某一天:100个应该换单的包裹
|
||||
- 其中:80个在考核期限内完成
|
||||
- 预期:24H换单率 = 80 / 100 × 100% = 80%
|
||||
|
||||
---
|
||||
|
||||
## 最终输出
|
||||
|
||||
### 清晰的表述
|
||||
|
||||
必须能够清楚地说出:
|
||||
|
||||
**"24H换单率 = ________ / ________ × 100%"**
|
||||
|
||||
例如:
|
||||
- "24H换单率 = 高标签率考核通过数 / 高标签率应该换单数 × 100%"
|
||||
- "其中高标签率考核通过数来自DailyHighLabelRateAssessed,......"
|
||||
- "其中高标签率应该换单数来自DailyHighLabelRateShould,......"
|
||||
|
||||
Reference in New Issue
Block a user