59 lines
1.4 KiB
SQL
59 lines
1.4 KiB
SQL
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 ;
|