上传源代码版本

This commit is contained in:
Im-Jenisson
2026-06-01 16:30:29 +08:00
commit b2a9b7d3c2
462 changed files with 104365 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
# 到货信息统计 MySQL 语句分析 - 验证清单
- [x] 验证业务逻辑理解是否正确
- [x] 验证 MySQL 语句是否正确实现提单号优先的分组逻辑
- [x] 验证 MySQL 语句是否正确计算所有统计数据
- [x] 验证 MySQL 语句是否支持过滤条件
- [x] 验证 MySQL 语句的性能是否满足要求
- [x] 验证索引建议是否合理
- [x] 验证文档是否完整且可读
- [x] 验证 MySQL 语句是否可以直接在数据库中执行
- [x] 验证统计结果是否与预期一致
- [x] 验证所有测试要求是否满足

View File

@@ -0,0 +1,160 @@
# 到货信息统计 MySQL 语句
## 1. 基本统计语句
```sql
SELECT
COALESCE(l.BillOfLadingNumber, l.MasterPackageNumber, 'Unknown') AS `Key`,
c.CustomerCode AS CustomerCode,
COUNT(*) AS ArrivalOrderCount,
SUM(CASE WHEN l.Label IS NULL OR l.Label = '' THEN 1 ELSE 0 END) AS NoLabelDataCount,
SUM(CASE WHEN l.Label IS NOT NULL AND l.Label != '' THEN 1 ELSE 0 END) AS LabeledOrderCount,
CONCAT(ROUND((SUM(CASE WHEN l.Label IS NOT NULL AND l.Label != '' THEN 1 ELSE 0 END) / COUNT(*)) * 100, 2), '%') AS LabelRate,
(SELECT COUNT(*)
FROM label_scan_history s
WHERE s.NeutralWaybillNumber = l.NeutralWaybillNumber
AND s.Result = 0) AS ReplaceCompletedCount,
COUNT(*) - (SELECT COUNT(*)
FROM label_scan_history s
WHERE s.NeutralWaybillNumber = l.NeutralWaybillNumber
AND s.Result = 0) AS ReplacePendingCount,
(SELECT MIN(h.ReceiptTime)
FROM arrival_handover_forms h
WHERE h.HandoverNumber = COALESCE(l.BillOfLadingNumber, l.MasterPackageNumber)) AS ArrivalTime,
MAX(l.BillOfLadingNumber) AS BillOfLadingNumber,
MAX(l.MasterPackageNumber) AS MasterPackageNumber
FROM
label_replace_requests l
LEFT JOIN
customers c ON l.CustomerId = c.Id
WHERE
1=1
-- 客户ID过滤
AND (l.CustomerId = 1 OR 1 IS NULL)
-- 日期范围过滤
AND (l.CreatedAt >= '2026-01-01' OR '2026-01-01' IS NULL)
AND (l.CreatedAt <= '2026-12-31' OR '2026-12-31' IS NULL)
GROUP BY
COALESCE(l.BillOfLadingNumber, l.MasterPackageNumber, 'Unknown')
ORDER BY
l.CreatedAt DESC;
```
## 2. 优化版本(使用子查询优化扫描记录统计)
```sql
WITH scan_summary AS (
SELECT
NeutralWaybillNumber,
COUNT(*) AS ReturnedLabelCount
FROM
label_scan_history
WHERE
Result = 0
GROUP BY
NeutralWaybillNumber
),
arrival_summary AS (
SELECT
HandoverNumber,
MIN(ReceiptTime) AS MinReceiptTime
FROM
arrival_handover_forms
GROUP BY
HandoverNumber
)
SELECT
COALESCE(l.BillOfLadingNumber, l.MasterPackageNumber, 'Unknown') AS `Key`,
c.CustomerCode AS CustomerCode,
COUNT(*) AS ArrivalOrderCount,
SUM(CASE WHEN l.Label IS NULL OR l.Label = '' THEN 1 ELSE 0 END) AS NoLabelDataCount,
SUM(CASE WHEN l.Label IS NOT NULL AND l.Label != '' THEN 1 ELSE 0 END) AS LabeledOrderCount,
CONCAT(ROUND((SUM(CASE WHEN l.Label IS NOT NULL AND l.Label != '' THEN 1 ELSE 0 END) / COUNT(*)) * 100, 2), '%') AS LabelRate,
COALESCE(SUM(s.ReturnedLabelCount), 0) AS ReplaceCompletedCount,
COUNT(*) - COALESCE(SUM(s.ReturnedLabelCount), 0) AS ReplacePendingCount,
COALESCE(a.MinReceiptTime, b.MinReceiptTime) AS ArrivalTime,
MAX(l.BillOfLadingNumber) AS BillOfLadingNumber,
MAX(l.MasterPackageNumber) AS MasterPackageNumber
FROM
label_replace_requests l
LEFT JOIN
customers c ON l.CustomerId = c.Id
LEFT JOIN
scan_summary s ON l.NeutralWaybillNumber = s.NeutralWaybillNumber
LEFT JOIN
arrival_summary a ON l.BillOfLadingNumber = a.HandoverNumber
LEFT JOIN
arrival_summary b ON l.MasterPackageNumber = b.HandoverNumber
WHERE
1=1
-- 客户ID过滤
AND (l.CustomerId = 1 OR 1 IS NULL)
-- 日期范围过滤
AND (l.CreatedAt >= '2026-01-01' OR '2026-01-01' IS NULL)
AND (l.CreatedAt <= '2026-12-31' OR '2026-12-31' IS NULL)
GROUP BY
COALESCE(l.BillOfLadingNumber, l.MasterPackageNumber, 'Unknown')
ORDER BY
l.CreatedAt DESC;
```
## 3. 实现说明
### 3.1 分组逻辑
使用 `COALESCE` 函数实现提单号优先的分组逻辑:
-`BillOfLadingNumber` 不为 NULL 时,使用 `BillOfLadingNumber` 作为分组依据
-`BillOfLadingNumber` 为 NULL 时,使用 `MasterPackageNumber` 作为分组依据
- 当两者都为 NULL 时,使用 'Unknown' 作为分组依据
### 3.2 统计计算
- **到货订单数量**:使用 `COUNT(*)` 统计每个分组的记录数
- **无标签数据数量**:使用 `SUM(CASE WHEN l.Label IS NULL OR l.Label = '' THEN 1 ELSE 0 END)` 统计
- **已有标签订单数**:使用 `SUM(CASE WHEN l.Label IS NOT NULL AND l.Label != '' THEN 1 ELSE 0 END)` 统计
- **已有标签率**:计算已有标签订单数占总订单数的百分比
- **换单完成数量**:统计有扫描记录且结果为 0 的记录数
- **未换单完成数量**:总订单数减去换单完成数量
- **到货时间**:从到货交接单表中获取最早的收货时间
### 3.3 过滤条件
- **客户ID过滤**可根据需要修改客户ID值
- **日期范围过滤**:可根据需要修改日期范围
## 4. 性能优化建议
1. **索引优化**
-`label_replace_requests` 表上添加以下索引:
- `(CustomerId, CreatedAt)`
- `(BillOfLadingNumber)`
- `(MasterPackageNumber)`
-`label_scan_history` 表上添加索引:
- `(NeutralWaybillNumber, Result)`
-`arrival_handover_forms` 表上添加索引:
- `(HandoverNumber, ReceiptTime)`
2. **查询优化**
- 使用 CTE (Common Table Expressions) 减少重复子查询
- 避免在 GROUP BY 子句中使用复杂表达式
- 合理使用 JOIN 替代子查询
3. **数据量控制**
- 考虑添加分页功能,避免一次性返回大量数据
- 对于历史数据,可以考虑归档策略
## 5. 使用说明
1. **参数调整**
- 客户ID修改 `l.CustomerId = 1` 中的 1 为实际客户ID
- 日期范围:修改 `'2026-01-01'``'2026-12-31'` 为实际日期范围
2. **结果解释**
- `Key` 列:表示分组依据,可能是提单号、主包号或 'Unknown'
- 其他列:表示各统计指标
3. **注意事项**
- `Key` 是 MySQL 关键字,使用反引号包围
- 所有字符串参数都使用单引号包围
- 日期参数使用 'YYYY-MM-DD' 格式
- 可以根据实际需要修改示例值

View File

@@ -0,0 +1,71 @@
# 到货信息统计 MySQL 语句分析
## Overview
- **Summary**: 分析如何编写 MySQL 语句,在有提单号的情况下以提单号统计到货信息,无提单号的情况下以主包号统计到货信息
- **Purpose**: 提供一个统一的 SQL 语句,根据数据情况自动选择合适的分组依据
- **Target Users**: 开发人员、数据库管理员
## Goals
- 分析到货信息统计的业务逻辑
- 提供统一的 MySQL 语句实现
- 确保统计结果的准确性
- 优化查询性能
## Non-Goals (Out of Scope)
- 不修改现有代码
- 不涉及前端实现细节
- 不处理权限和安全问题
## Background & Context
在物流系统中,到货信息统计是一个常见需求。通常情况下,我们会按提单号进行统计,但在某些情况下(如没有提单号时),需要按主包号进行统计。当前实现可能需要编写多个 SQL 语句来处理不同情况,我们需要一个统一的解决方案。
## Functional Requirements
- **FR-1**: 当记录有提单号时,按提单号分组统计
- **FR-2**: 当记录没有提单号时,按主包号分组统计
- **FR-3**: 计算到货订单数量、无标签数据数量、已有标签率等统计数据
- **FR-4**: 支持按客户ID、日期范围等条件过滤
## Non-Functional Requirements
- **NFR-1**: 性能优化,避免全表扫描
- **NFR-2**: 代码可读性和可维护性
- **NFR-3**: 数据准确性
## Constraints
- **Technical**: 使用MySQL数据库
- **Business**: 无特殊业务约束
- **Dependencies**: 依赖 `label_replace_requests`
## Assumptions
- 数据库表结构已正确创建
- 所有必要的索引已添加
- 数据量在合理范围内
## Acceptance Criteria
### AC-1: 基本统计功能
- **Given**: 存在带有提单号的记录
- **When**: 执行统计查询
- **Then**: 按提单号分组统计
- **Verification**: `programmatic`
### AC-2: 无提单号情况
- **Given**: 存在没有提单号但有主包号的记录
- **When**: 执行统计查询
- **Then**: 按主包号分组统计
- **Verification**: `programmatic`
### AC-3: 性能优化
- **Given**: 数据量较大如10万条记录
- **When**: 执行查询
- **Then**: 查询响应时间在可接受范围内(<5秒
- **Verification**: `programmatic`
### AC-4: 数据准确性
- **Given**: 存在测试数据
- **When**: 执行查询并与手动计算结果比较
- **Then**: 统计数据与手动计算一致
- **Verification**: `human-judgment`
## Open Questions
- [ ] 如何处理既没有提单号也没有主包号的记录
- [ ] 是否需要考虑性能优化的索引策略

View File

@@ -0,0 +1,53 @@
# 到货信息统计 MySQL 语句分析 - 实现计划
## [x] Task 1: 分析业务逻辑
- **Priority**: P0
- **Depends On**: None
- **Description**:
- 分析到货信息统计的业务逻辑
- 确定分组依据的优先级(提单号优先,无提单号时使用主包号)
- 识别需要统计的字段和计算逻辑
- **Acceptance Criteria Addressed**: AC-1, AC-2, AC-4
- **Test Requirements**:
- `human-judgment` TR-1.1: 理解业务逻辑
- `human-judgment` TR-1.2: 确定分组策略
- **Notes**: 重点关注如何处理既没有提单号也没有主包号的记录
## [x] Task 2: 编写 MySQL 语句
- **Priority**: P0
- **Depends On**: Task 1
- **Description**:
- 编写统一的 MySQL 语句,实现按提单号或主包号分组统计
- 包含所有必要的统计计算
- 支持过滤条件
- **Acceptance Criteria Addressed**: AC-1, AC-2, AC-4
- **Test Requirements**:
- `programmatic` TR-2.1: 验证 SQL 语句的正确性
- `human-judgment` TR-2.2: 确保语句可读性
- **Notes**: 使用 COALESCE 函数来实现优先级逻辑
## [x] Task 3: 性能优化分析
- **Priority**: P1
- **Depends On**: Task 2
- **Description**:
- 分析 SQL 语句的性能
- 识别可能的优化点
- 提供索引建议
- **Acceptance Criteria Addressed**: AC-3
- **Test Requirements**:
- `human-judgment` TR-3.1: 分析查询执行计划
- `human-judgment` TR-3.2: 评估索引使用情况
- **Notes**: 考虑使用 EXPLAIN 分析查询执行计划
## [x] Task 4: 编写完整的文档
- **Priority**: P1
- **Depends On**: Task 2, Task 3
- **Description**:
- 编写详细的 SQL 语句文档
- 包含参数说明和使用示例
- 提供性能优化建议
- **Acceptance Criteria Addressed**: AC-1, AC-2, AC-3, AC-4
- **Test Requirements**:
- `human-judgment` TR-4.1: 文档完整性
- `human-judgment` TR-4.2: 文档可读性
- **Notes**: 确保文档包含所有必要的信息