DROP procedure IF EXISTS `vn`.`zone_getLeaves`; DELIMITER $$ CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zone_getLeaves`( vSelf INT, vParentFk INT, vSearch VARCHAR(255) ) BEGIN DECLARE vIsNumber BOOL; DECLARE vIsSearch BOOL DEFAULT vSearch IS NOT NULL AND vSearch != ''; DROP TEMPORARY TABLE IF EXISTS tNodes; CREATE TEMPORARY TABLE tNodes (UNIQUE (id)) ENGINE = MEMORY SELECT id FROM zoneGeo LIMIT 0; IF vIsSearch THEN SET vIsNumber = vSearch REGEXP '^[0-9]+$'; INSERT INTO tNodes SELECT id FROM zoneGeo WHERE (vIsNumber AND `name` = vSearch) OR (!vIsNumber AND `name` LIKE CONCAT('%', vSearch, '%')) LIMIT 1000; ELSEIF vParentFk IS NULL THEN INSERT INTO tNodes SELECT geoFk FROM zoneIncluded WHERE zoneFk = vSelf; END IF; IF vParentFk IS NULL THEN DROP TEMPORARY TABLE IF EXISTS tChilds; CREATE TEMPORARY TABLE tChilds ENGINE = MEMORY SELECT id FROM tNodes; DROP TEMPORARY TABLE IF EXISTS tParents; CREATE TEMPORARY TABLE tParents ENGINE = MEMORY SELECT id FROM zoneGeo LIMIT 0; myLoop: LOOP DELETE FROM tParents; INSERT INTO tParents SELECT parentFk id FROM zoneGeo g JOIN tChilds c ON c.id = g.id WHERE g.parentFk IS NOT NULL; INSERT IGNORE INTO tNodes SELECT id FROM tParents; IF ROW_COUNT() = 0 THEN LEAVE myLoop; END IF; DELETE FROM tChilds; INSERT INTO tChilds SELECT id FROM tParents; END LOOP; DROP TEMPORARY TABLE tChilds, tParents; END IF; IF !vIsSearch THEN INSERT IGNORE INTO tNodes SELECT id FROM zoneGeo WHERE parentFk <=> vParentFk; END IF; SELECT g.id, g.`name`, g.parentFk, g.sons, isIncluded selected FROM zoneGeo g JOIN tNodes n ON n.id = g.id LEFT JOIN zoneIncluded i ON i.geoFk = g.id AND i.zoneFk = vSelf ORDER BY depth, selected DESC, `name`; DROP TEMPORARY TABLE tNodes; END$$ DELIMITER ;