获取MySQL中所有分层类别的父级

时间:2011-11-08 04:39:05

标签: mysql sql hierarchical-data

我有一个类似于以下内容的表

cat_id  | name            |   parent_id |   Level
-------------------------------------------------
1         cat1                0             1
2         subcat1             1             2
3         subcat1-subcat      2             3

我想知道获得cat_id 3类别的最有效方法是什么,所以我的结果集看起来像这样

cat_id  | name            |   parent_id |   Level
--------------------------------------------------
1         cat1                0             1
2         subcat1             1             2

3 个答案:

答案 0 :(得分:1)

您必须执行多个查询。每个级别的一个你想要去(或把它写成一个存储过程)。

最有效的方法是不使用所谓的“邻接列表模型”(你正在使用的),而是切换到“嵌套集”。

谷歌搜索“嵌套集”将为您提供大量信息。这需要一些时间来习惯它,并编写处理它的代码。

答案 1 :(得分:1)

我遇到了同样的问题,但不幸的是在单一查询中无法做到这一点。所以你必须编写一个函数或一个可以获得所有父类别的存储过程。 算法将如下

**childs** = 3
Loop (not done)
 Get immediate parents of **childs**, 
 save(concat) them in a *return* variable
 update **childs** = immediate parents
REPEAT

return 将包含给定类别

的所有父级(单位)

1)功能:在函数的情况下,你将返回一个字符串值,因为函数不能返回超过1的值,所以你的结果将是" 1,2"。但这又不能完全满足我们的目的,因为我们必须在查询中使用此结果

 SELECT * FROM table_name where id IN ("1,2") ORDER BY LEVEL

所以我们将把结果作为正则表达式返回;)那就是" ^(1 | 2)$"

 SELECT * FROM tbl_categories WHERE cat_id REGEXP "^(1|2)$" ORDER BY level;

2)存储过程:在存储过程的情况下,我们可以动态地准备一个语句,并在执行该查询时,我们将得到我们所需的结果。

有关存储过程请求的更多详细信息,请参阅以下教程。

Get all nested parents of a category – MySQL

答案 2 :(得分:0)

以下是存储过程,您可以使用它来获取层次级别的所有父级:


DROP PROCEDURE IF EXISTS sp_GetParentsByLevel;
    delimiter $$

CREATE PROCEDURE `sp_GetParentsByLevel`(level_id varchar(36)) main : BEGIN DECLARE P_ID VARCHAR(36) DEFAULT NULL; DECLARE P_ID_ALL TEXT DEFAULT NULL; DECLARE COUNT INT DEFAULT 0; get_parents : LOOP -- get the parent of current level SELECT parent_id INTO P_ID FROM test1 WHERE cat_id = level_id; -- if current level is parent level then leave the loop IF P_ID = 0 THEN LEAVE get_parents; END IF; -- set current parent id as level id for next iteration SET level_id = P_ID; -- concat all the parents id IF COUNT = 0 THEN SET P_ID_ALL = P_ID; SET COUNT = COUNT+1; ELSE SET P_ID_ALL = CONCAT(P_ID_ALL,',',P_ID); END IF; END LOOP get_parents; -- if parent exists then execute the query, else return empty set IF P_ID_ALL IS NOT NULL THEN -- create query to generate result set SET @sqltext = CONCAT('SELECT cat_id, name, parent_id FROM test1 WHERE cat_id IN (',P_ID_ALL,')'); -- execute query PREPARE stmt FROM @sqltext; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ mysql> CALL sp_GetParentsByLevel('3'); +--------+---------+-----------+ | cat_id | name | parent_id | +--------+---------+-----------+ | 1 | cat1 | 0 | | 2 | subcat1 | 1 | +--------+---------+-----------+ 2 rows in set (0.00 sec)

CALL sp_GetParentsByLevel('3');

请替换表名。此存储过程可用于获取任意数量的父项。