DROP PROCEDURE IF EXISTS `vn`.`zone_getFromGeo`; DELIMITER $$ CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zone_getFromGeo`(vGeoFk INT) BEGIN /** * Returns available zones for the passed address. * * @param vAddress The address id * @return tmp.zone(id) The available zones */ DECLARE vChildFk INT DEFAULT vGeoFk; DECLARE vParentFk INT; DECLARE vLevel INT DEFAULT 1; DROP TEMPORARY TABLE IF EXISTS tNodes; CREATE TEMPORARY TABLE tNodes (PRIMARY KEY (id)) ENGINE = MEMORY SELECT vGeoFk id, vLevel `level`; myLoop: LOOP SELECT parentFk INTO vParentFk FROM zoneGeo WHERE id = vChildFk; SET vChildFk = vParentFk; SET vLevel = vLevel + 1; INSERT IGNORE INTO tNodes SELECT vChildFk, vLevel FROM DUAL WHERE vChildFk IS NOT NULL; IF ROW_COUNT() = 0 THEN LEAVE myLoop; END IF; END LOOP; DROP TEMPORARY TABLE IF EXISTS tmp.zone; CREATE TEMPORARY TABLE tmp.zone (INDEX (id)) SELECT id FROM ( SELECT zoneFk id, isIncluded FROM ( SELECT i.zoneFk, i.isIncluded FROM tNodes n JOIN zoneIncluded i ON i.geoFk = n.id ORDER BY zoneFk, n.`level` ) t GROUP BY id HAVING isIncluded ) t; DROP TEMPORARY TABLE tNodes; END$$ DELIMITER ;