USE `vn`; DROP procedure IF EXISTS `zone_upcomingDeliveries`; DELIMITER $$ USE `vn`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `zone_upcomingDeliveries`() BEGIN DECLARE vForwardDays INT; SELECT forwardDays INTO vForwardDays FROM zoneConfig; CALL util.time_createTable(CURDATE(), DATE_ADD(CURDATE(), INTERVAL vForwardDays DAY)); DROP TEMPORARY TABLE IF EXISTS tLandings; CREATE TEMPORARY TABLE tLandings (INDEX (eventFk)) ENGINE = MEMORY SELECT e.id eventFk, @travelingDays := IFNULL(e.travelingDays, z.travelingDays) travelingDays, TIMESTAMPADD(DAY, @travelingDays, ti.dated) landed, ti.dated shipped FROM zone z JOIN zoneEvent e ON e.zoneFk = z.id JOIN tmp.time ti ON ti.dated BETWEEN curdate() AND TIMESTAMPADD(DAY, vForwardDays, curdate()); DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption; CREATE TEMPORARY TABLE tmp.zoneOption ENGINE = MEMORY SELECT * FROM ( SELECT z.id zoneFk, TIME(IFNULL(e.`hour`, z.`hour`)) `hour`, l.travelingDays, IFNULL(e.price, z.price) price, IFNULL(e.bonus, z.bonus) bonus, l.landed, l.shipped FROM zone z JOIN zoneEvent e ON e.zoneFk = z.id JOIN tLandings l ON l.eventFk = e.id WHERE ( e.`type` = 'day' AND e.`dated` = l.landed ) OR ( e.`type` != 'day' AND e.weekDays & (1 << WEEKDAY(l.landed)) AND (e.`started` IS NULL OR l.landed >= e.`started`) AND (e.`ended` IS NULL OR l.landed <= e.`ended`) ) ORDER BY zoneFk, CASE WHEN e.`type` = 'day' THEN 1 WHEN e.`type` = 'range' THEN 2 ELSE 3 END ) t GROUP BY zoneFk, landed; DELETE t FROM tmp.zoneOption t JOIN zoneExclusion e ON e.zoneFk = t.zoneFk AND e.`dated` = t.landed; SELECT MAX(zo.`hour`) `hour`, zg.`name`, zo.shipped FROM tmp.zoneOption zo JOIN `zone` z ON z.id = zo.zoneFk JOIN agencyMode am ON am.id = z.agencyModeFk JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk JOIN zoneIncluded zi ON zi.zoneFk = z.id JOIN zoneGeo zg ON zg.id = zi.geoFk AND zg.type = 'province' WHERE dm.code = 'DELIVERY' GROUP BY shipped, zg.`name` ORDER BY shipped, zg.`name`; DROP TEMPORARY TABLE tmp.time, tLandings; END$$ DELIMITER ;