1

想象一下,我有一个表(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,然后在有结果时再次将所有结果连接到一个字符串中,但这太慢了......

4

3 回答 3

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 ;
于 2013-10-06T17:17:54.670 回答
0

这是您查询的 sqlfiddle 演示 http://sqlfiddle.com/#!2/ca90e/6

如果可以有“n”个孩子,那么您需要使用存储过程

于 2013-10-06T13:55:32.893 回答
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 ;

调用 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)
于 2013-10-06T14:25:21.610 回答