DROP PROCEDURE IF EXISTS adjust_visit_dates; CREATE PROCEDURE adjust_visit_dates() BEGIN DECLARE encounters_after_visit_stop_date CURSOR FOR SELECT v.visit_id AS visit_id, max(e.encounter_datetime) AS updated_visit_date_stopped FROM encounter e JOIN visit v ON v.visit_id = e.visit_id WHERE v.date_stopped < e.encounter_datetime GROUP BY v.visit_id ORDER BY v.visit_id; DECLARE encounters_before_visit_start_date CURSOR FOR SELECT v.visit_id AS visit_id, min(e.encounter_datetime) AS updated_visit_date_stopped FROM encounter e JOIN visit v ON v.visit_id = e.visit_id WHERE v.date_started > e.encounter_datetime GROUP BY v.visit_id ORDER BY v.visit_id; OPEN encounters_after_visit_stop_date; BEGIN DECLARE done INT DEFAULT FALSE; DECLARE visit_id_to_be_updated INT; DECLARE updated_visit_date_stopped DATETIME; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; read_loop: LOOP FETCH encounters_after_visit_stop_date INTO visit_id_to_be_updated, updated_visit_date_stopped; IF done THEN LEAVE read_loop; END IF; UPDATE visit AS v SET v.date_stopped = updated_visit_date_stopped WHERE v.visit_id = visit_id_to_be_updated; END LOOP; END; OPEN encounters_before_visit_start_date; BEGIN DECLARE done INT DEFAULT FALSE; DECLARE visit_id_to_be_updated INT; DECLARE updated_visit_date_stopped DATETIME; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; read_loop: LOOP FETCH encounters_before_visit_start_date INTO visit_id_to_be_updated, updated_visit_date_stopped; IF done THEN LEAVE read_loop; END IF; UPDATE visit AS v SET v.date_started = updated_visit_date_stopped WHERE v.visit_id = visit_id_to_be_updated; END LOOP; END; END; CALL adjust_visit_dates();