今天发现了之前的一段sql,查询起来特别慢,于是决定优化一番,最终调整效果显著(4.6s-0.25s),现在来看看吧。
原始sql,一共599条数据,查询用时4.6s
select xx.* from ( select m.*, (case when m.plan_type = 'academic' then ( select count(1) from nurse_edu_academic_plan_service_member apsm where apsm.plan_id = m.id and apsm.delete_bit = 0 ) when m.plan_type = 'operate' then ( select count(1) from nurse_edu_operate_plan_service_member opsm where opsm.plan_id = m.id and opsm.delete_bit = 0 ) when m.plan_type = 'practice' then ( select count(1) from nurse_edu_practice_plan_service_member ppsm where ppsm.plan_id = m.id and ppsm.delete_bit = 0 ) when m.plan_type = 'training' then ( select count(1) from nurse_edu_training_plan_service_member tpsm where tpsm.plan_id = m.id and tpsm.delete_bit = 0 ) when m.plan_type = 'course' then ( SELECT count(1) FROM `nurse_edu_course_plan_service_member` AS cpsm where cpsm.plan_id = m.id and cpsm.delete_bit = 0 ) when m.plan_type = 'courseware' then ( SELECT count(1) FROM `nurse_edu_courseware_plan_service_member` AS cpsm where cpsm.plan_id = m.id and cpsm.delete_bit = 0 ) else 0 end ) as personCount, (case when m.plan_type = 'academic' then ( select count(1) from nurse_edu_academic_plan_service_member apsm where apsm.plan_id = m.id and (apsm.exam_status = 'completed' ) and apsm.delete_bit = 0 ) when m.plan_type = 'operate' then ( select count(1) from nurse_edu_operate_plan_service_member opsm where opsm.plan_id = m.id and (opsm.exam_status = 'completed' or opsm.exam_status = 'doing' ) and opsm.delete_bit = 0 ) when m.plan_type = 'practice' then ( ifnull(n.practiceActualNum,0) ) when m.plan_type = 'training' then ( case when m.planCompleteCondition = 'sign_in' then ( select count(1) from nurse_edu_training_plan_service_member tpsm where tpsm.plan_id = m.id and IFNULL(tpsm.sign_in, 0) = 1 and tpsm.delete_bit = 0 ) when m.planCompleteCondition = 'sign_out' then ( select count(1) from nurse_edu_training_plan_service_member tpsm where tpsm.plan_id = m.id and IFNULL(tpsm.sign_out, 0) = 1 and tpsm.delete_bit = 0 ) when m.planCompleteCondition = 'exam' then ( select count(1) from nurse_edu_training_plan_service_member tpsm where tpsm.plan_id = m.id and ( tpsm.exam_actual_end_time is not null ) and tpsm.delete_bit = 0 ) when m.planCompleteCondition = 'questionnaire' then ( select count(1) from nurse_edu_training_plan_implement_questionnaire tpiq where tpiq.plan_id = m.id and tpiq.service_member_id in ( select tpsm.id from nurse_edu_training_plan_service_member tpsm where tpsm.plan_id = m.id ) ) when (m.planCompleteCondition = '' or m.planCompleteCondition is null) then ( select count(1) from nurse_edu_training_plan_service_member tpsm where tpsm.plan_id = m.id and tpsm.delete_bit = 0 ) else '' end ) when m.plan_type = 'course' then ( SELECT count(1) FROM `nurse_edu_course_plan_service_member` AS cpsm LEFT JOIN (SELECT plan_id,COUNT(1) as sumNum FROM nurse_edu_course_video WHERE delete_bit=0 GROUP BY plan_id) AS cv ON cv.plan_id=cpsm.plan_id AND cpsm.delete_bit=0 LEFT JOIN ( SELECT service_member_id,COUNT(course_video_id) AS cnt FROM (SELECT service_member_id,course_video_id FROM `nurse_edu_course_plan_implement_video` WHERE CONCAT('0-',video_total_duration)=video_play_recording GROUP BY service_member_id,course_video_id) AS f GROUP BY service_member_id ) AS t ON t.service_member_id=cpsm.id WHERE cpsm.plan_id= m.id and (case when m.planCompleteCondition = 'exam' then (case when ( cpsm.exam_actual_end_time IS NOT NULL ) THEN 1 ELSE 0 END) when m.planCompleteCondition = 'played' then (ROUND(t.cnt/cv.sumNum,2)) else 0 end)=1 ) when m.plan_type = 'courseware' then ( SELECT count(1) FROM `nurse_edu_courseware_plan_service_member` AS cpsm LEFT JOIN nurse_edu_courseware_plan_implement_view AS iv ON iv.service_member_id=cpsm.id AND cpsm.delete_bit=0 WHERE cpsm.plan_id=m.id and ( case when m.planCompleteCondition = 'exam' then (case when ( cpsm.exam_actual_end_time IS NOT NULL ) THEN 1 ELSE 0 END) when m.planCompleteCondition = 'viewed' then (case when IFNULL(iv.view_total_duration,0)>0 then 1 else 0 end) else 0 end)=1 ) else 0 end ) as actualCompletePepoleCount, ( case when (m.plan_type = 'training' and m.plan_status = 'undone' and CURRENT_TIMESTAMP > m.plan_end_time) then ( 'completed' ) when (m.plan_status = 'undone' and CURRENT_TIMESTAMP < m.plan_start_time) then ( 'nostart' ) when (m.plan_status = 'undone' and m.plan_start_time < CURRENT_TIMESTAMP and CURRENT_TIMESTAMP < m.plan_end_time) then ( 'doing' ) else m.plan_status end ) as queryPlanStatus from (SELECT CONCAT(IFNULL(aps.plan_complete_pepole_count, ''), IFNULL(ops.plan_complete_pepole_count, ''), IFNULL(pps.plan_complete_people_count, ''), IFNULL(cps.plan_complete_people_count, ''), IFNULL(tps.plan_complete_people_count, ''), IFNULL(cwps.plan_complete_people_count, '')) AS planCompletePepoleCount, CONCAT(IFNULL(pps.target_complete_percentage, ''), IFNULL(cps.plan_complete_condition, ''),IFNULL(tps.plan_complete_condition, ''), IFNULL(cwps.plan_complete_condition, '')) AS planCompleteCondition, IFNULL(tps.out_lecturer_user_names, '') AS outLecturerUserNames, IFNULL(tps.out_lecturer_user_phones, '') AS outLecturerUserPhones, IFNULL(tps.already_send_sms_phones, '') AS alreadySendSmsPhones, a.*, item.plan_add_member_range as planAddMemberRange FROM `nurse_edu_item_plan` AS a left join nurse_edu_item as item on item.id = a.item_id LEFT JOIN nurse_edu_academic_plan_service AS aps ON a.id = aps.plan_id AND aps.delete_bit = 0 LEFT JOIN nurse_edu_operate_plan_service as ops ON a.id = ops.plan_id AND ops.delete_bit = 0 LEFT JOIN nurse_edu_practice_plan_service AS pps ON a.id = pps.plan_id AND pps.delete_bit = 0 LEFT JOIN nurse_edu_course_plan_service AS cps ON a.id = cps.plan_id AND cps.delete_bit = 0 LEFT JOIN nurse_edu_training_plan_service as tps ON a.id = tps.plan_id AND tps.delete_bit = 0 LEFT JOIN nurse_edu_courseware_plan_service AS cwps ON a.id = cwps.plan_id ANd cwps.delete_bit = 0 WHERE IFNULL(a.make_up_belong_plan_id,0) = 0 AND a.delete_bit = 0 ) m left join ( select count(1) as practiceActualNum, pp.planId as planId from ( SELECT (case when IFNULL(ROUND(100 * COUNT(cs.id) / p.all_subject_count, 2), 0) >= p.target_complete_percentage then 'done' else 'undone' end) AS completeStatus, ip.id as planId FROM `nurse_edu_practice_plan_service` as p LEFT JOIN nurse_edu_item_plan AS ip ON p.plan_id = ip.id LEFT JOIN nurse_edu_practice_plan_service_member AS ppsm ON p.id = ppsm.service_id AND p.delete_bit = '0' AND ppsm.delete_bit = '0' LEFT JOIN nurse_edu_practice_complete_subject as cs ON cs.service_member_id = ppsm.id GROUP BY ppsm.member_user_id,planId ) pp where pp.completeStatus='done' GROUP BY planId ) n on m.id = n.planId ) xx where 1=1 ORDER BY xx.create_time desc,xx.last_update_time desc
第一次优化,整体查询耗时0.9s
SQL中使用了较多的子查询,子查询会影响查询速度
去除子查询部分,耗时0.88s,查询速度有明显变化
原sql中,使用case when做大量条件判断+子查询,处理不同情况下的数据展示。可以尝试使用left join替代子查询,那就需要将每一种情况写成一个子表,再根据条件关联主表显示数据
统计总人数的子表查询
实际完成人数子表查询
与主表的关联条件
第一次优化后sql
select xx.* from ( select m.*, ff.personCount, mm.actualCompletePepoleCount, ( case when (m.plan_type = 'training' and m.plan_status = 'undone' and CURRENT_TIMESTAMP > m.plan_end_time) then ( 'completed' ) when (m.plan_status = 'undone' and CURRENT_TIMESTAMP < m.plan_start_time) then ( 'nostart' ) when (m.plan_status = 'undone' and m.plan_start_time < CURRENT_TIMESTAMP and CURRENT_TIMESTAMP < m.plan_end_time) then ( 'doing' ) else m.plan_status end ) as queryPlanStatus from ( SELECT CONCAT(IFNULL(aps.plan_complete_pepole_count, ''), IFNULL(ops.plan_complete_pepole_count, ''), IFNULL(pps.plan_complete_people_count, ''), IFNULL(cps.plan_complete_people_count, ''), IFNULL(tps.plan_complete_people_count, ''), IFNULL(cwps.plan_complete_people_count, '')) AS planCompletePepoleCount, CONCAT(IFNULL(pps.target_complete_percentage, ''), IFNULL(cps.plan_complete_condition, ''),IFNULL(tps.plan_complete_condition, ''), IFNULL(cwps.plan_complete_condition, '')) AS planCompleteCondition, IFNULL(tps.out_lecturer_user_names, '') AS outLecturerUserNames, IFNULL(tps.out_lecturer_user_phones, '') AS outLecturerUserPhones, IFNULL(tps.already_send_sms_phones, '') AS alreadySendSmsPhones, a.*, item.plan_add_member_range as planAddMemberRange FROM `nurse_edu_item_plan` AS a left join nurse_edu_item as item on item.id = a.item_id LEFT JOIN nurse_edu_academic_plan_service AS aps ON a.id = aps.plan_id AND aps.delete_bit = 0 LEFT JOIN nurse_edu_operate_plan_service as ops ON a.id = ops.plan_id AND ops.delete_bit = 0 LEFT JOIN nurse_edu_practice_plan_service AS pps ON a.id = pps.plan_id AND pps.delete_bit = 0 LEFT JOIN nurse_edu_course_plan_service AS cps ON a.id = cps.plan_id AND cps.delete_bit = 0 LEFT JOIN nurse_edu_training_plan_service as tps ON a.id = tps.plan_id AND tps.delete_bit = 0 LEFT JOIN nurse_edu_courseware_plan_service AS cwps ON a.id = cwps.plan_id ANd cwps.delete_bit = 0 WHERE IFNULL(a.make_up_belong_plan_id,0) = 0 AND a.delete_bit = 0 ) m left join ( select m.plan_id,count(1) as personCount from nurse_edu_academic_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_operate_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_practice_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_training_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_course_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_courseware_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id ) ff on ff.plan_id = m.id left join ( select m.plan_id,count(1) as actualCompletePepoleCount,'academic' as actualType from nurse_edu_academic_plan_service_member m where m.exam_status = 'completed' and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'operate' as actualType from nurse_edu_operate_plan_service_member m where (m.exam_status = 'completed' or m.exam_status = 'doing') and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_sign_in' as actualType from nurse_edu_training_plan_service_member m where IFNULL(m.sign_in, 0) = 1 and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_sign_out' as actualType from nurse_edu_training_plan_service_member m where IFNULL(m.sign_out, 0) = 1 and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_exam' as actualType from nurse_edu_training_plan_service_member m where m.exam_actual_end_time is not null and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_questionnaire' as actualType from nurse_edu_training_plan_implement_questionnaire m GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_other' as actualType from nurse_edu_training_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'course_exam' FROM `nurse_edu_course_plan_service_member` AS cpsm WHERE cpsm.exam_actual_end_time IS NOT NULL and cpsm.delete_bit=0 GROUP BY cpsm.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'course_played' FROM `nurse_edu_course_plan_service_member` AS cpsm LEFT JOIN (SELECT plan_id,COUNT(1) as sumNum FROM nurse_edu_course_video WHERE delete_bit=0 GROUP BY plan_id) AS cv ON cv.plan_id=cpsm.plan_id AND cpsm.delete_bit=0 LEFT JOIN ( SELECT service_member_id,COUNT(course_video_id) AS cnt FROM (SELECT service_member_id,course_video_id FROM `nurse_edu_course_plan_implement_video` WHERE CONCAT('0-',video_total_duration)=video_play_recording GROUP BY service_member_id,course_video_id) AS f GROUP BY service_member_id ) AS t ON t.service_member_id=cpsm.id WHERE cpsm.exam_actual_end_time IS NOT NULL and ROUND(t.cnt/cv.sumNum,2) = 1 GROUP BY cpsm.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'courseware_exam' as actualType FROM `nurse_edu_courseware_plan_service_member` AS cpsm LEFT JOIN nurse_edu_courseware_plan_implement_view AS iv ON iv.service_member_id=cpsm.id AND cpsm.delete_bit=0 WHERE cpsm.exam_actual_end_time IS NOT NULL GROUP BY cpsm.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'courseware_viewed' as actualType FROM `nurse_edu_courseware_plan_service_member` AS cpsm LEFT JOIN nurse_edu_courseware_plan_implement_view AS iv ON iv.service_member_id=cpsm.id AND cpsm.delete_bit=0 WHERE IFNULL(iv.view_total_duration,0)>0 GROUP BY cpsm.plan_id union all select pp.planId as planId, count(1) as actualCompletePepoleCount,'practice' as actualType from ( SELECT (case when IFNULL(ROUND(100 * COUNT(cs.id) / p.all_subject_count, 2), 0) >= p.target_complete_percentage then 'done' else 'undone' end) AS completeStatus, ip.id as planId FROM `nurse_edu_practice_plan_service` as p LEFT JOIN nurse_edu_item_plan AS ip ON p.plan_id = ip.id LEFT JOIN nurse_edu_practice_plan_service_member AS ppsm ON p.id = ppsm.service_id AND p.delete_bit = '0' AND ppsm.delete_bit = '0' LEFT JOIN nurse_edu_practice_complete_subject as cs ON cs.service_member_id = ppsm.id GROUP BY ppsm.member_user_id,planId ) pp where pp.completeStatus='done' GROUP BY planId ) mm on m.id = mm.plan_id and (case when m.plan_type = 'academic' and mm.actualType = 'academic' then 1 when m.plan_type = 'operate' and mm.actualType = 'operate' then 1 when m.plan_type = 'practice' and mm.actualType = 'practice' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'sign_in' and mm.actualType = 'trainging_sign_in' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'sign_out' and mm.actualType = 'training_sign_out' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'exam' and mm.actualType = 'training_exam' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'questionnaire' and mm.actualType = 'training_questionnaire' then 1 when m.plan_type ='training' and (m.planCompleteCondition = '' or m.planCompleteCondition is null) and mm.actualType = 'training_other' then 1 when m.plan_type = 'course' and m.planCompleteCondition = 'exam' and mm.actualType = 'courseware_exam' then 1 when m.plan_type = 'course' and m.planCompleteCondition = 'viewed' and mm.actualType = 'courseware_viewed' then 1 when m.plan_type = 'courseware' and m.planCompleteCondition = 'exam' and mm.actualType = 'course_exam' then 1 when m.plan_type = 'courseware' and m.planCompleteCondition = 'played' and mm.actualType = 'course_played' then 1 else 0 end) = 1 ) xx where 1=1 ORDER BY xx.create_time desc,xx.last_update_time desc
第二次优化,整体耗时0.25s
经查,主体部分sql执行,耗时0.5s左右,增加索引执行无明显变化
尝试将相同业务数据表放在一起查询必要字段,再与主业务关联,耗时0.07s
优化后整体sql
select xx.* from ( select m.*, ff.personCount, mm.actualCompletePepoleCount, ( case when (m.plan_type = 'training' and m.plan_status = 'undone' and CURRENT_TIMESTAMP > m.plan_end_time) then ( 'completed' ) when (m.plan_status = 'undone' and CURRENT_TIMESTAMP < m.plan_start_time) then ( 'nostart' ) when (m.plan_status = 'undone' and m.plan_start_time < CURRENT_TIMESTAMP and CURRENT_TIMESTAMP < m.plan_end_time) then ( 'doing' ) else m.plan_status end ) as queryPlanStatus from ( SELECT a.*, bb.planCompletePepoleCount, bb.planCompleteCondition, bb.outLecturerUserNames, bb.outLecturerUserPhones, bb.alreadySendSmsPhones, item.plan_add_member_range as planAddMemberRange FROM `nurse_edu_item_plan` AS a left join nurse_edu_item as item on item.id = a.item_id left join ( select aps.plan_complete_pepole_count as planCompletePepoleCount,'' as planCompleteCondition,'' AS outLecturerUserNames,'' AS outLecturerUserPhones,'' AS alreadySendSmsPhones,aps.plan_id as planId from nurse_edu_academic_plan_service AS aps where aps.delete_bit = 0 union all select ops.plan_complete_pepole_count as planCompletePepoleCount,'' as planCompleteCondition,'' AS outLecturerUserNames,'' AS outLecturerUserPhones,'' AS alreadySendSmsPhones,ops.plan_id as planId from nurse_edu_operate_plan_service AS ops where ops.delete_bit = 0 union all select pps.plan_complete_people_count as planCompletePepoleCount,pps.target_complete_percentage as planCompleteCondition,'' AS outLecturerUserNames,'' AS outLecturerUserPhones,'' AS alreadySendSmsPhones,pps.plan_id as planId from nurse_edu_practice_plan_service AS pps where pps.delete_bit = 0 union all select cps.plan_complete_people_count as planCompletePepoleCount,cps.plan_complete_condition as planCompleteCondition,'' AS outLecturerUserNames,'' AS outLecturerUserPhones,'' AS alreadySendSmsPhones,cps.plan_id as planId from nurse_edu_course_plan_service AS cps where cps.delete_bit = 0 union all select tps.plan_complete_people_count as planCompletePepoleCount,tps.plan_complete_condition as planCompleteCondition,IFNULL(tps.out_lecturer_user_names, '') AS outLecturerUserNames,IFNULL(tps.out_lecturer_user_phones, '') AS outLecturerUserPhones,IFNULL(tps.already_send_sms_phones, '') AS alreadySendSmsPhones,tps.plan_id as planId from nurse_edu_training_plan_service AS tps where tps.delete_bit = 0 union all select cwps.plan_complete_people_count as planCompletePepoleCount,cwps.plan_complete_condition as planCompleteCondition,'' AS outLecturerUserNames,'' AS outLecturerUserPhones,'' AS alreadySendSmsPhones,cwps.plan_id as planId from nurse_edu_courseware_plan_service AS cwps where cwps.delete_bit = 0 ) bb on a.id = bb.planId WHERE IFNULL(a.make_up_belong_plan_id,0) = 0 AND a.delete_bit = 0 ) m left join ( select m.plan_id,count(1) as personCount from nurse_edu_academic_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_operate_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_practice_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_training_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_course_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as personCount from nurse_edu_courseware_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id) ff on ff.plan_id = m.id left join ( select m.plan_id,count(1) as actualCompletePepoleCount,'academic' as actualType from nurse_edu_academic_plan_service_member m where m.exam_status = 'completed' and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'operate' as actualType from nurse_edu_operate_plan_service_member m where (m.exam_status = 'completed' or m.exam_status = 'doing') and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_sign_in' as actualType from nurse_edu_training_plan_service_member m where IFNULL(m.sign_in, 0) = 1 and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_sign_out' as actualType from nurse_edu_training_plan_service_member m where IFNULL(m.sign_out, 0) = 1 and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_exam' as actualType from nurse_edu_training_plan_service_member m where m.exam_actual_end_time is not null and m.delete_bit = 0 GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_questionnaire' as actualType from nurse_edu_training_plan_implement_questionnaire m GROUP BY m.plan_id union all select m.plan_id,count(1) as actualCompletePepoleCount,'training_other' as actualType from nurse_edu_training_plan_service_member m where m.delete_bit = 0 GROUP BY m.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'course_exam' FROM `nurse_edu_course_plan_service_member` AS cpsm WHERE cpsm.exam_actual_end_time IS NOT NULL and cpsm.delete_bit=0 GROUP BY cpsm.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'course_played' FROM `nurse_edu_course_plan_service_member` AS cpsm LEFT JOIN (SELECT plan_id,COUNT(1) as sumNum FROM nurse_edu_course_video WHERE delete_bit=0 GROUP BY plan_id) AS cv ON cv.plan_id=cpsm.plan_id AND cpsm.delete_bit=0 LEFT JOIN ( SELECT service_member_id,COUNT(course_video_id) AS cnt FROM (SELECT service_member_id,course_video_id FROM `nurse_edu_course_plan_implement_video` WHERE CONCAT('0-',video_total_duration)=video_play_recording GROUP BY service_member_id,course_video_id) AS f GROUP BY service_member_id ) AS t ON t.service_member_id=cpsm.id WHERE cpsm.exam_actual_end_time IS NOT NULL and ROUND(t.cnt/cv.sumNum,2) = 1 GROUP BY cpsm.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'courseware_exam' as actualType FROM `nurse_edu_courseware_plan_service_member` AS cpsm LEFT JOIN nurse_edu_courseware_plan_implement_view AS iv ON iv.service_member_id=cpsm.id AND cpsm.delete_bit=0 WHERE cpsm.exam_actual_end_time IS NOT NULL GROUP BY cpsm.plan_id union all SELECT cpsm.plan_id,count(1) as actualCompletePepoleCount,'courseware_viewed' as actualType FROM `nurse_edu_courseware_plan_service_member` AS cpsm LEFT JOIN nurse_edu_courseware_plan_implement_view AS iv ON iv.service_member_id=cpsm.id AND cpsm.delete_bit=0 WHERE IFNULL(iv.view_total_duration,0)>0 GROUP BY cpsm.plan_id union all select pp.planId as planId, count(1) as actualCompletePepoleCount,'practice' as actualType from ( SELECT (case when IFNULL(ROUND(100 * COUNT(cs.id) / p.all_subject_count, 2), 0) >= p.target_complete_percentage then 'done' else 'undone' end) AS completeStatus, ip.id as planId FROM `nurse_edu_practice_plan_service` as p LEFT JOIN nurse_edu_item_plan AS ip ON p.plan_id = ip.id LEFT JOIN nurse_edu_practice_plan_service_member AS ppsm ON p.id = ppsm.service_id AND p.delete_bit = '0' AND ppsm.delete_bit = '0' LEFT JOIN nurse_edu_practice_complete_subject as cs ON cs.service_member_id = ppsm.id GROUP BY ppsm.member_user_id,planId ) pp where pp.completeStatus='done' GROUP BY planId ) mm on m.id = mm.plan_id and (case when m.plan_type = 'academic' and mm.actualType = 'academic' then 1 when m.plan_type = 'operate' and mm.actualType = 'operate' then 1 when m.plan_type = 'practice' and mm.actualType = 'practice' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'sign_in' and mm.actualType = 'trainging_sign_in' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'sign_out' and mm.actualType = 'training_sign_out' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'exam' and mm.actualType = 'training_exam' then 1 when m.plan_type ='training' and m.planCompleteCondition = 'questionnaire' and mm.actualType = 'training_questionnaire' then 1 when m.plan_type ='training' and (m.planCompleteCondition = '' or m.planCompleteCondition is null) and mm.actualType = 'training_other' then 1 when m.plan_type = 'course' and m.planCompleteCondition = 'exam' and mm.actualType = 'courseware_exam' then 1 when m.plan_type = 'course' and m.planCompleteCondition = 'viewed' and mm.actualType = 'courseware_viewed' then 1 when m.plan_type = 'courseware' and m.planCompleteCondition = 'exam' and mm.actualType = 'course_exam' then 1 when m.plan_type = 'courseware' and m.planCompleteCondition = 'played' and mm.actualType = 'course_played' then 1 else 0 end) = 1 ) xx where 1=1 ORDER BY xx.create_time desc,xx.last_update_time desc
发表评论