wlzboy
4 天以前 c098f1e3a3e052aa3d65584aae6dc003a70d75ad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
-- ========================================
-- 修复GPS分段里程的任务关联
-- 用途:为已有的分段里程数据补充 task_id 和 task_code
-- 优化说明:补充task_id后,统计计算将使用优化方案(直接SQL聚合,更快)
-- ========================================
 
-- 1. 查看当前未关联任务的分段数量
SELECT COUNT(*) as '未关联任务的分段数' 
FROM tb_vehicle_gps_segment_mileage 
WHERE task_id IS NULL;
 
-- 2. 查看有多少任务可以被关联
SELECT COUNT(DISTINCT t.task_id) as '可关联的任务数'
FROM sys_task t
INNER JOIN sys_task_vehicle tv ON t.task_id = tv.task_id
WHERE t.del_flag = '0'
  AND t.task_status NOT IN ('PENDING', 'CANCELLED');
 
-- 3. 更新逻辑:根据车辆ID和时间重叠关联任务
-- 注意:这个查询会比较慢,建议分批执行或在非高峰期执行
 
UPDATE tb_vehicle_gps_segment_mileage seg
INNER JOIN (
    SELECT 
        seg2.segment_id,
        t.task_id,
        t.task_code
    FROM tb_vehicle_gps_segment_mileage seg2
    INNER JOIN sys_task_vehicle tv ON seg2.vehicle_id = tv.vehicle_id
    INNER JOIN sys_task t ON tv.task_id = t.task_id
    WHERE seg2.task_id IS NULL
      AND t.del_flag = '0'
      -- AND t.task_status NOT IN ('PENDING', 'CANCELLED')
      -- 时间重叠条件:分段开始时间 < 任务结束时间 AND 分段结束时间 > 任务开始时间
      AND seg2.segment_start_time < COALESCE(t.actual_end_time, t.planned_end_time, DATE_ADD(t.create_time, INTERVAL 24 HOUR))
      AND seg2.segment_end_time > COALESCE(t.actual_start_time, t.planned_start_time, t.create_time)
    GROUP BY seg2.segment_id, t.task_id, t.task_code
) task_match ON seg.segment_id = task_match.segment_id
SET 
    seg.task_id = task_match.task_id,
    seg.task_code = task_match.task_code;
 
-- 4. 查看修复结果
SELECT 
    '已关联任务' as '类型',
    COUNT(*) as '数量',
    CONCAT(ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM tb_vehicle_gps_segment_mileage), 2), '%') as '占比'
FROM tb_vehicle_gps_segment_mileage 
WHERE task_id IS NOT NULL
UNION ALL
SELECT 
    '未关联任务' as '类型',
    COUNT(*) as '数量',
    CONCAT(ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM tb_vehicle_gps_segment_mileage), 2), '%') as '占比'
FROM tb_vehicle_gps_segment_mileage 
WHERE task_id IS NULL;
 
-- 5. 查看每个车辆的关联情况
SELECT 
    seg.vehicle_id,
    seg.vehicle_no,
    COUNT(*) as '总分段数',
    SUM(CASE WHEN seg.task_id IS NOT NULL THEN 1 ELSE 0 END) as '已关联分段数',
    CONCAT(ROUND(SUM(CASE WHEN seg.task_id IS NOT NULL THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2), '%') as '关联率'
FROM tb_vehicle_gps_segment_mileage seg
GROUP BY seg.vehicle_id, seg.vehicle_no
ORDER BY COUNT(*) DESC
LIMIT 20;
 
-- 6. 分析未能关联的原因
-- 查看某个未关联分段的详细信息
SELECT 
    seg.segment_id,
    seg.vehicle_id,
    seg.vehicle_no,
    seg.segment_start_time,
    seg.segment_end_time,
    '该时段该车辆的任务' as '说明',
    t.task_id,
    t.task_code,
    t.task_status,
    t.create_time,
    COALESCE(t.actual_start_time, t.planned_start_time) as '任务开始时间',
    COALESCE(t.actual_end_time, t.planned_end_time) as '任务结束时间'
FROM tb_vehicle_gps_segment_mileage seg
LEFT JOIN sys_task_vehicle tv ON seg.vehicle_id = tv.vehicle_id
LEFT JOIN sys_task t ON tv.task_id = t.task_id
    AND t.del_flag = '0'
    AND seg.segment_start_time < COALESCE(t.actual_end_time, t.planned_end_time, DATE_ADD(t.create_time, INTERVAL 24 HOUR))
    AND seg.segment_end_time > COALESCE(t.actual_start_time, t.planned_start_time, t.create_time)
WHERE seg.task_id IS NULL
ORDER BY seg.segment_start_time DESC
LIMIT 10;
 
-- ========================================
-- 使用说明:
-- 1. 先执行查询语句(1、2)查看数据情况
-- 2. 在非高峰期执行更新语句(3)
-- 3. 执行结果查询(4、5、6)验证修复效果
-- 4. 如果数据量大,建议添加 LIMIT 分批执行
-- ========================================
 
-- ========================================
-- 预防措施:确保定时任务正常运行
-- ========================================
 
-- 7. 检查GPS分段里程计算定时任务状态
SELECT 
    job_id,
    job_name,
    job_group,
    invoke_target,
    cron_expression,
    status as '状态(0=正常,1=暂停)',
    create_time,
    update_time
FROM sys_job
WHERE job_name LIKE '%GPS%' OR job_name LIKE '%里程%'
ORDER BY create_time DESC;
 
-- 8. 如果定时任务是暂停状态,启动它
-- UPDATE sys_job SET status = '0' WHERE job_name = 'GPS分段里程实时计算';
 
-- 9. 检查最近的GPS计算记录
SELECT 
    vehicle_id,
    vehicle_no,
    MAX(segment_end_time) as '最后计算时间',
    COUNT(*) as '分段数',
    SUM(CASE WHEN task_id IS NOT NULL THEN 1 ELSE 0 END) as '有任务关联的分段数'
FROM tb_vehicle_gps_segment_mileage
WHERE segment_end_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY vehicle_id, vehicle_no
ORDER BY MAX(segment_end_time) DESC;