我的生产数据看起来类似于此处解释的邻接列表模型...
http://mysql.stu.edu.tw/tech-resources/articles/hierarchical-data.html
我的问题是如何知道嵌套有多深?在这种情况下,从最后一个叶子"Flash"到第一个节点"Electronics"是4.是否有返回此最大深度数的查询?
MYSQL没有CTE也没有递归功能.你可以用'经典循环'来解决它:
DELIMITER $$
DROP FUNCTION IF EXISTS figure_up_depth $$
--encapsulated as a function:
CREATE FUNCTION figure_up_depth(idToSearch INT) RETURNS INT BEGIN
--var to count steps from node to root:
DECLARE depth INT;
SET depth = 1;
--while we are not on root node:
WHILE ( idToSearch is not null) DO
SET idToSearch = ( select parent
from category
where category_id = idToSearch
);
SET depth = depth + 1;
END WHILE;
RETURN depth;
END;
$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
检查:
mysql> select figure_up_depth(7);
+--------------------+
| figure_up_depth(7) |
+--------------------+
| 4 |
+--------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
2015年7月8日编辑
我意识到OP要求最大深度,而不是节点深度.一个简单的:
mysql> select max( figure_up_depth(category_id) ) as max_depth
from category;
Run Code Online (Sandbox Code Playgroud)
如果性能重要,正确的解决方案是:
categories.parent放在临时表中table1.categories.id = table1.id,将结果连接字段categories.parent放在临时表上table2.table1并重命名table2为table1.table1有行,请转到步骤2 .循环次数迭代将是树深度:
DELIMITER $$
DROP PROCEDURE IF EXISTS letsgo;
CREATE PROCEDURE letsgo() BEGIN
DECLARE R int;
DECLARE D int;
SET D=0;
DROP TEMPORARY TABLE IF EXISTS children;
CREATE TEMPORARY TABLE children AS (SELECT category_id as id
FROM category
WHERE parent is NULL );
DROP TEMPORARY TABLE IF EXISTS children_prev;
CREATE TEMPORARY TABLE children_prev AS (SELECT * FROM children );
SET R = ( SELECT count(*) FROM children );
WHILE ( R > 0 ) DO
DROP TEMPORARY TABLE IF EXISTS children_aux;
CREATE TEMPORARY TABLE children_aux AS (
SELECT category_id as id
FROM category R
INNER JOIN children_prev C on C.id = R.parent
);
SET R = ( SELECT count(*) FROM children_aux );
INSERT INTO children
SELECT * FROM children_aux;
TRUNCATE TABLE children_prev;
INSERT INTO children_prev
SELECT * FROM children_aux;
SET D=D+1;
END WHILE;
SELECT D;
END;
$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
测试:
mysql> call letsgo();
+------+
| D |
+------+
| 4 |
+------+
1 row in set (0.14 sec)
Run Code Online (Sandbox Code Playgroud)
注意:抱歉脏解决方案,这是mysql:没有CTE,没有递归,没有选择函数递归,没有DO-While,...