この質問は、まだ最初の検索結果の1つとして表示されます。だから私は私の解決策を共有したいと思います、そしてそれがより多くの人々を助けることを願っています。これは、多くのレベルの親子関係を持つテーブルがある場合にも機能します。それはかなり遅い解決策ですが。トップレベルはNULL
親として持っています。
+---------+---------+
| id | parent |
+---------+---------+
| 1 | NULL |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
+---------+---------+
id
私のアプローチでは、再帰的に自分自身を呼び出し、要求された親に到達するまで、要求された親のパスの前にパスを追加し続けるプロシージャを使用しますNULL
。
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `PATH`(IN `input` INT, OUT `output` VARCHAR(128))
BEGIN
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _path VARCHAR(128);
SET `max_sp_recursion_depth` = 50;
SELECT `id`, `parent`
INTO _id, _parent
FROM `database`.`table`
WHERE `table`.`id` = `input`;
IF _parent IS NULL THEN
SET _path = _id;
ELSE
CALL `PATH`(_parent, _path);
SELECT CONCAT(_path, '-', _id) INTO _path;
END IF;
SELECT _path INTO `output`;
END $$
DELIMITER ;
句で結果を使用するには、の結果をラップORDER BY
するtooも必要になります。FUNCTION
PROCEDURE
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `GETPATH`(`input` INT) RETURNS VARCHAR(128)
BEGIN
CALL `PATH`(`input`, @path);
RETURN @path;
END $$
DELIMITER ;
これで、再帰パスを使用してテーブルの順序を並べ替えることができます。10000行のテーブルでは、ワークステーションで1秒強かかります。
SELECT `id`, `parent`, GETPATH(`id`) `path` FROM `database`.`table` ORDER BY `GETPATH`(`id`);
出力例:
+---------+---------+---------------+
| id | parent | path |
+---------+---------+---------------+
| 1 | NULL | 1 |
| 10 | 1 | 1-10 |
| 300 | 10 | 1-10-300 |
| 301 | 300 | 1-10-300-301 |
| 302 | 300 | 1-10-300-302 |
+---------+---------+---------------+
5 rows in set (1,39 sec)