USE `vn`; DROP procedure IF EXISTS `zone_upcomingDeliveries`; DELIMITER $$ USE `vn`$$ CREATE 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.tTime 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 zo.*, zg.`name`, (ELT(WEEKDAY(zo.shipped) + 1, 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo')) weekday FROM tmp.zoneOption zo JOIN zone z ON z.id = zo.zoneFk JOIN zoneIncluded zi ON zi.zoneFk = z.id JOIN zoneGeo zg ON zg.id = zi.geoFk AND zg.depth = 1 WHERE z.`name` like '%zon%' GROUP BY shipped, zg.`name` ORDER BY shipped, zg.`name`; DROP TEMPORARY TABLE tmp.tTime, tLandings; END$$ DELIMITER ;