sql >> データベース >  >> RDS >> Mysql

MySQL:特定のノードで葉を見つける方法

    単一のクエリでこれを行う方法はありません。あったとしても、おそらく非常に非効率的でしょう。

    ストアドプロシージャとループを使用してこれを行うことができます。追加したインデックスを使用すると、かなり高速になるはずです。これは、入力テーブル(A)からノードを選択し、ノードとその子を(B)に挿入する2つのテーブルを使用します。次に、BをAに交換し、Aに非リーフノードが存在しなくなるまで繰り返します。ループの反復は、入力ノードと最後のリーフノードの間のレベルと同じ数になるだけです。ほとんどの場合、おそらくそれほど深くはありません。このストアドプロシージャは、コードで外部的に実行するよりも高速です。

    参考までに、インストールで一時テーブルを処理するのに問題がありました。「エラー2」が発生した場合は、一時キーワードを削除してください。

    delimiter $$
    drop procedure if exists GetLeafNodes $$
    create procedure GetLeafNodes(nodeid int)
    begin
    declare N int default 1;
    
    -- create two working sets of IDs, we'll go back and forth between these two sets
    drop temporary table if exists A;
    drop temporary table if exists B;
    create temporary table A(node int, child int);
    create temporary table B(node int, child int);
    
    -- insert our single input node into the working set
    insert into A values (null, nodeid);
    
    while (N>0) do
      -- keep selecting child nodes for each node we are now tracking
      -- leaf nodes will end up with the child set to null
      insert into B
      select ifnull(A.child,A.node), tree.ID
        from A
        left outer join DATA_TREE as tree on A.child=tree.parent_id;
    
      -- now swap A and B
      rename table A to temp, B to A, temp to B;
    
      -- remove non-leaf nodes from table B
      delete from B;
    
      -- exit when there are no longer any non-leaf nodes in A
      set N=(select count(*) from A where child is not null);
    end while;
    
    -- now output our list of leaf nodes
    select node from A;
    
    drop temporary table A;
    drop temporary table B;
    end $$
    DELIMITER ;
    call GetLeafNodes(4);
    

    テストには次のサンプルセットを使用しました:

    CREATE TABLE `DATA_TREE` (
      `ID` int(11) NOT NULL,
      `PARENT_ID` int(11) NOT NULL,
      PRIMARY KEY (`ID`),
      UNIQUE KEY `ID_UNIQUE` (`ID`),
      KEY `fk_DATA_TREE_1_idx` (`PARENT_ID`)
    ) ENGINE=InnoDB
    ;
    
    insert into DATA_TREE values
    (1,0),(2,1),(3,1),(4,1),(5,3),(6,3),(7,4),(8,4),(9,4),(10,6),(11,6),(12,7),(13,9),(14,9),(15,12),(16,12),(17,12),(18,14);
    



    1. フィジカル・スタンバイ・データベースのMRPのORA-01111

    2. JasperReportsを使用してOracleのblob列から画像を表示するにはどうすればよいですか?

    3. 2つのMySQLテーブル間で欠落している値を見つける方法

    4. 本番PostgreSQLデータベースの管理を容易にする