1

子 - >親の関係 (カテゴリと複数レベルのサブカテゴリ) を持つテーブル (Mysql myISAM) があるとします。

+--------+---------+
| id     |parent_id|
+--------+---------+
| 1      |  null   |
| 2      |    1    |
| 3      |    2    |
| 4      |    7    |
| 5      |    1    |
| 6      |    5    |
+--------+---------+

id 1 を照会すると 2,5,3,6 が出力されるように、ある ID のすべての子をどのように検索しますか? (順序は重要ではありません)

つまり、このparent_linkで元に戻された子のルックアップを行う方法は?

現時点では、php を循環させ、parent_id を照会してから、結果がある間にすべての結果を文字列に連結しますが、これは非常に遅いです...

4

3 に答える 3

1

OK、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 ;

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)
于 2013-10-06T14:25:21.610 に答える