-- ========================================
|
-- 修复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;
|