上传源代码版本
This commit is contained in:
180
.trae/documents/24h_rate_root_cause_final_diagnosis.md
Normal file
180
.trae/documents/24h_rate_root_cause_final_diagnosis.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# 24H换单率超过100%的最终根本原因确诊
|
||||
|
||||
**问题**:24H换单率异常高达4745%、17924%等
|
||||
|
||||
**根本原因**:LEFT JOIN 产生的笛卡尔积
|
||||
|
||||
---
|
||||
|
||||
## 当前24H换单率的精确定义
|
||||
|
||||
### SQL 代码位置
|
||||
|
||||
**文件**:`d:\EPproject\LabelReplaceServer\src\DAL\Repositories\LabelReplaceRepository.cs`
|
||||
|
||||
**第1154-1162行**(外层SELECT):
|
||||
```sql
|
||||
CASE
|
||||
WHEN 高标签率应该换单数 = 0 THEN '0.00%'
|
||||
ELSE CONCAT(ROUND(
|
||||
高标签率考核通过数
|
||||
/ 高标签率应该换单数 * 100, 2), '%')
|
||||
END AS 24H换单率
|
||||
```
|
||||
|
||||
### 分子和分母定义
|
||||
|
||||
**分子**:`高标签率考核通过数`
|
||||
- **来源**:第1207行,来自 CTE `DailyHighLabelRateAssessed`
|
||||
- **定义**:16点前考核通过包裹数 + 16点后考核通过包裹数
|
||||
- **SQL代码**:`COALESCE(dhras.高标签率考核通过数, 0) AS 高标签率考核通过数`
|
||||
|
||||
**分母**:`高标签率应该换单数`
|
||||
- **来源**:第1209行,来自 CTE `DailyHighLabelRateShould`
|
||||
- **定义**:所有冻结标签率≥80%的交接单数
|
||||
- **SQL代码**:`COALESCE(dhlrs.高标签率应该换单数, 0) AS 高标签率应该换单数`
|
||||
|
||||
### 完整的计算公式
|
||||
|
||||
```
|
||||
24H换单率 = (高标签率考核通过数 / 高标签率应该换单数) × 100%
|
||||
|
||||
其中:
|
||||
高标签率考核通过数 = 16点前考核通过包裹数 + 16点后考核通过包裹数
|
||||
高标签率应该换单数 = 冻结标签率≥80%的交接单中的全部包裹数
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 为什么结果超过100%?
|
||||
|
||||
### 根本原因:LEFT JOIN 导致的笛卡尔积
|
||||
|
||||
**问题代码**(第1222-1223行):
|
||||
```sql
|
||||
LEFT JOIN DailyHighLabelRateAssessed dhras ON t.日期 = dhras.日期
|
||||
LEFT JOIN DailyHighLabelRateShould dhlrs ON t.日期 = dhlrs.日期
|
||||
```
|
||||
|
||||
**问题分析**:
|
||||
|
||||
1. **DailyHighLabelRateAssessed CTE**(第1037-1046行)
|
||||
```sql
|
||||
DailyHighLabelRateAssessed AS (
|
||||
SELECT
|
||||
日期,
|
||||
SUM(16点前考核通过包裹数) + SUM(16点后考核通过包裹数) AS 高标签率考核通过数
|
||||
FROM (
|
||||
SELECT 日期, 16点前考核通过包裹数, 0 AS 16点后考核通过包裹数 FROM DailyBeforeNoonPassed
|
||||
UNION ALL
|
||||
SELECT 日期, 0 AS 16点前考核通过包裹数, 16点后考核通过包裹数 FROM DailyAfternoonPassed
|
||||
) t
|
||||
GROUP BY 日期
|
||||
)
|
||||
```
|
||||
|
||||
**问题**:这个CTE中,UNION ALL 后的子查询每个日期可能有**2行**(一行来自 DailyBeforeNoonPassed,一行来自 DailyAfternoonPassed)。然后 SUM() + SUM() 应该会聚合,但...
|
||||
|
||||
2. **实际的问题**:DailyBeforeNoonPassed 或 DailyAfternoonPassed 本身可能有**多行同一日期的记录**,这导致 UNION ALL 后产生多行,GROUP BY 日期后...仍然可能有多行!
|
||||
|
||||
3. **结果**:
|
||||
- 如果 DailyHighLabelRateAssessed 的某个日期有 10 行
|
||||
- DailyHighLabelRateShould 的某个日期有 1 行
|
||||
- LEFT JOIN 后,产生 10 行
|
||||
- 主SELECT 中,这 10 行的每一行都计算了一次 24H换单率
|
||||
- 最后数据库返回 10 行相同的 24H换单率(4745% × 10 = 47450%?)
|
||||
|
||||
---
|
||||
|
||||
## 具体的修复方案
|
||||
|
||||
### 修复方式1:在各CTE中加DISTINCT(快速修复)
|
||||
|
||||
**对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 日期
|
||||
)
|
||||
```
|
||||
|
||||
### 修复方式2:在主SELECT中加GROUP BY(根本修复)
|
||||
|
||||
**在外层SELECT后加**:
|
||||
```sql
|
||||
) AS subquery
|
||||
GROUP BY 日期 -- 新增这一行
|
||||
ORDER BY 日期 DESC
|
||||
```
|
||||
|
||||
这样可以确保每个日期只返回一行。
|
||||
|
||||
### 修复方式3:检查DailyBeforeNoonPassed和DailyAfternoonPassed是否真的有多行
|
||||
|
||||
**运行诊断查询**:
|
||||
```sql
|
||||
SELECT 日期, COUNT(*) as 行数
|
||||
FROM DailyBeforeNoonPassed
|
||||
GROUP BY 日期
|
||||
HAVING 行数 > 1;
|
||||
|
||||
SELECT 日期, COUNT(*) as 行数
|
||||
FROM DailyAfternoonPassed
|
||||
GROUP BY 日期
|
||||
HAVING 行数 > 1;
|
||||
```
|
||||
|
||||
如果有多行,说明这两个CTE本身有问题。
|
||||
|
||||
---
|
||||
|
||||
## 推荐的立即修复
|
||||
|
||||
### 快速方案(无需修改CTE)
|
||||
|
||||
在第1228行(`ORDER BY t.日期`)之前,在 SELECT 语句的最外层加 GROUP BY:
|
||||
|
||||
**从**:
|
||||
```sql
|
||||
) AS subquery
|
||||
ORDER BY 日期 DESC
|
||||
```
|
||||
|
||||
**改为**:
|
||||
```sql
|
||||
) AS subquery
|
||||
GROUP BY 日期
|
||||
ORDER BY 日期 DESC
|
||||
```
|
||||
|
||||
这样可以确保每个日期只有一行数据返回。
|
||||
|
||||
---
|
||||
|
||||
## 最终确认
|
||||
|
||||
**24H换单率的精确定义**:
|
||||
|
||||
```
|
||||
24H换单率 = (高标签率考核通过数 / 高标签率应该换单数) × 100%
|
||||
|
||||
分子:高标签率考核通过数
|
||||
= 16点前考核通过包裹数 + 16点后考核通过包裹数
|
||||
来自:DailyHighLabelRateAssessed CTE
|
||||
|
||||
分母:高标签率应该换单数
|
||||
= 冻结标签率≥80%的交接单中的全部包裹数
|
||||
来自:DailyHighLabelRateShould CTE
|
||||
|
||||
业务含义:
|
||||
在24小时内,冻结标签率≥80%的交接单中,
|
||||
有多少比例的包裹在规定的考核时间内完成了换单
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user