我有一个类似于以下内容的表
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
答案 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)存储过程:在存储过程的情况下,我们可以动态地准备一个语句,并在执行该查询时,我们将得到我们所需的结果。
有关存储过程请求的更多详细信息,请参阅以下教程。
答案 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');
请替换表名。此存储过程可用于获取任意数量的父项。