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

ツリー形式のMYSQL出力またはレベルの追加(親-子)

    単一のクエリでは実行できませんが、ストアドプロシージャで実行できます...唯一の前提条件として、「C1」と「C2」が存在することを表すために、既存のサンプルテーブルにさらに2つのレコードを追加する必要があります。トップレベル...「Parent」フィールドが空白で、子レベルが「C1」で、もう1つが「C2」であるレコードを追加します。これにより、最上位の親レベルが「準備」されます。後続の階層の関連付けのために、そうでない場合は、最上位階層の開始「基礎」がありません。また、「主キー」列も必要です(このスクリプトでは、「IDMyTable」として1倍のシーケンシャルで作成しましたが、代わりに使用するためにテーブルに自動インクリメント列があると想定しています)。

    構築方法を示すためにすべての出力列を含めましたが、このルーチンの前提は、期待される列出力に基づいてテーブルを作成することですが、構築中に階層表現をダウンストリームに保持するために追加されます。レイヤーが深くなるにつれて正しい方向を維持することを確認するために、「ID」列を連結しています。最終的な結果セットでどのように機能するかを確認できます。

    次に、最終的な結果セットで、階層データの深さに基づいてスペースを事前にパディングします。

    ループは、前の結果セットで見つかった親に基づいてレコードを追加しますが、IDがまだ追加されていない場合に限ります(重複を防止します)...

    循環順序が常に追加される方法を確認するには、順序なしで最後のクエリを実行し、各反復がどのように修飾され、前の階層レベルが追加されたかを確認します...

    -- --------------------------------------------------------------------------------
    -- Routine DDL
    -- Note: comments before and after the routine body will not be stored by the server
    -- --------------------------------------------------------------------------------
    DELIMITER $$
    
    CREATE DEFINER=`root`@`localhost` PROCEDURE `GetHierarchy2`()
    BEGIN
        -- prepare a hierarchy level variable 
        set @hierlvl := 00000;
    
        -- prepare a variable for total rows so we know when no more rows found
        set @lastRowCount := 0;
    
        -- pre-drop temp table
        drop table if exists MyHierarchy;
    
        -- now, create it as the first level you want... 
        -- ie: a specific top level of all "no parent" entries
        -- or parameterize the function and ask for a specific "ID".
        -- add extra column as flag for next set of ID's to load into this.
        create table MyHierarchy as
        select 
                t1.IDMyTable,
                t1.Child AS Parent,
                @hierlvl as IDHierLevel,
                cast( t1.IDMyTable as char(100)) FullHierarchy
            from
                MyTable t1
            where
                    t1.Parent is null
                OR t1.Parent = '';
    
    
        -- how many rows are we starting with at this tier level
        set @lastRowCount := ROW_COUNT();
    
        -- we need to have a "primary key", otherwise our UPDATE
        -- statement will nag about an unsafe update command
        alter table MyHierarchy add primary key (IDMyTable);
    
    
        -- NOW, keep cycling through until we get no more records
        while @lastRowCount > 0 do
    
            -- NOW, load in all entries found from full-set NOT already processed
            insert into MyHierarchy
                select 
                        t1.IDMyTable,
                        t1.Child as Parent,
                        h1.IDHierLevel +1 as IDHierLevel,
                        concat_ws( ',', h1.FullHierarchy, t1.IDMyTable ) as FullHierarchy
                    from
                        MyTable t1
                            join MyHierarchy h1
                                on t1.Parent = h1.Parent
                        left join
                            MyHierarchy h2
                                on t1.IDMyTable = h2.IDMyTable
                    where
                        h2.IDMyTable is null;
    
    
            set @lastRowCount := row_count();
    
            -- now, update the hierarchy level
            set @hierLevel := @hierLevel +1;
    
        end while;
    
    
        -- return the final set now
        select 
                *, concat( lpad( ' ', 1 + (IDHierLevel * 3 ), ' ' ), Parent ) as ShowHierarchy
            from MyHierarchy
            order by FullHierarchy;
    
    END
    


    1. 画像をデータベースに直接保存しますか、それともbase64データとして保存しますか?

    2. javascriptでphpスクリプトを実行しますか?

    3. SQLデータ型を理解する–SQLデータ型について知っておくべきことすべて

    4. INSERTステートメント内でサブクエリを使用できますか?