想象一下,我有一个表(Mysql myISAM),其中包含子 - >父关系(类别和子类别的多个级别)
+--------+---------+
| id |parent_id|
+--------+---------+
| 1 | null |
| 2 | 1 |
| 3 | 2 |
| 4 | 7 |
| 5 | 1 |
| 6 | 5 |
+--------+---------+
你怎么能找到一些ID的所有孩子,比如查询id 1会输出: 2,5,3,6? (顺序没有重要性)
换句话说,如何在这个parent_link上进行恢复的子查找?
目前,我在php中循环并查询parent_id,然后再次在字符串中连接所有结果,但结果却很慢......
答案 0 :(得分:1)
好的,感谢Deepak代码,我设法编写了这个,可读性稍差,它接受一个表作为参数,并返回元素的深度。
DELIMITER $$
CREATE PROCEDURE get_children(IN V_KEY INT,IN SOURCETABLE VARCHAR(255))
proc:
BEGIN
DECLARE vid text;
DECLARE count int;
DROP TABLE IF EXISTS `temp_child_nodes`;
CREATE TEMPORARY TABLE temp_child_nodes(id int, depth int);
SET vid = V_KEY;
SET @val = '';
SET count = 0;
WHILE (vid is NOT NULL) DO
SET @sql = CONCAT("INSERT INTO temp_child_nodes(id,depth) SELECT id,'",count,"' from ",SOURCETABLE," where parent_id IN (",vid,")");
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET @tsql = CONCAT("SELECT GROUP_CONCAT(id) INTO @val from ",SOURCETABLE," where parent_id IN (", vid, ")");
PREPARE stmt2 FROM @tsql;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET vid = @val;
SET count = count + 1;
END WHILE;
#output data
SELECT * from temp_child_nodes;
END
$$
DELIMITER ;
答案 1 :(得分:0)
以下是您的查询的sqlfiddle演示 http://sqlfiddle.com/#!2/ca90e/6
如果可能有'n'个孩子,那么你需要使用存储过程
答案 2 :(得分:0)
create table my_table(
id int,
parent_id int
);
insert into my_table values
(1,null),
(2,1),
(3,2),
(4,7),
(5,1),
(6,5);
此存储过程将为您提供任何给定ID的所有子项
DELIMITER $$
DROP PROCEDURE IF EXISTS get_children$$
CREATE PROCEDURE get_children(IN V_KEY INT)
proc:
BEGIN
DECLARE vid text;
declare oid text;
DECLARE count int;
CREATE TEMPORARY TABLE temp_child_nodes(
id int
);
SET vid = V_KEY;
INSERT INTO temp_child_nodes(id) SELECT id from my_table where parent_id = vid;
SELECT GROUP_CONCAT(concat("'",id,"'")) INTO oid from my_table where parent_id = vid;
SET vid = oid;
SET count = 0;
SET @val = '';
WHILE (vid is NOT NULL) DO
SET @sql = CONCAT("INSERT INTO temp_child_nodes(id) SELECT id from my_table where parent_id IN (",vid,")");
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET @tsql = CONCAT("SELECT GROUP_CONCAT(id) INTO @val from my_table where parent_id IN (", vid, ")");
PREPARE stmt2 FROM @tsql;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET vid = @val;
SET count = count + 1;
END WHILE;
#SELECT count;
SELECT * from temp_child_nodes;
#SELECT oid;
END
$$
DELIMITER ;
CALL get_children(1);
mysql> CALL get_children(1);
+------+
| id |
+------+
| 2 |
| 5 |
| 3 |
| 6 |
+------+
4 rows in set (0.22 sec)
Query OK, 0 rows affected (0.22 sec)