DELIMITER $$ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`unary_leaves`(v_top INT) BEGIN /** * A partir de un nodo devuelve todos sus descendientes. * * @table tmp.tree Tabla con los ids de los nodos descendientes; **/ DECLARE v_count INT; DECLARE v_parent INT; DECLARE v_depth INT DEFAULT 0; DROP TEMPORARY TABLE IF EXISTS tmp.tree; CREATE TEMPORARY TABLE tmp.tree (INDEX (id)) ENGINE = MEMORY SELECT v_top id, v_parent parent, v_depth depth; DROP TEMPORARY TABLE IF EXISTS tmp.parent; CREATE TEMPORARY TABLE tmp.parent ENGINE = MEMORY SELECT v_top id; l: LOOP SET v_depth = v_depth + 1; DROP TEMPORARY TABLE IF EXISTS tmp.child; CREATE TEMPORARY TABLE tmp.child ENGINE = MEMORY SELECT c.`id`, c.parent FROM `unary` c JOIN tmp.parent p ON c.`parent` = p.id; DROP TEMPORARY TABLE tmp.parent; CREATE TEMPORARY TABLE tmp.parent ENGINE = MEMORY SELECT c.id, c.parent FROM tmp.child c LEFT JOIN tmp.tree t ON t.id = c.id WHERE t.id IS NULL; INSERT INTO tmp.tree SELECT id, parent, v_depth FROM tmp.parent; SELECT COUNT(*) INTO v_count FROM tmp.parent; IF v_count = 0 THEN LEAVE l; END IF; END LOOP; DROP TEMPORARY TABLE tmp.parent, tmp.child; END$$ DELIMITER ;