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

親と子で並べ替えられたMySQLツリー

    Mike Hillyerのブログに示されている方法以外に、階層データを整理する方法は他にもあります。 推移閉包テーブルと呼ぶメソッドを使用するのが好きです または略してクロージャーテーブル。この設計では、階層内のすべてのパスを祖先/子孫のペアとして格納します。

    create table closure (
        ancestor int,
        descendant int,
        length int,
        primary key (ancestor,descendant),
        key (descendant,ancestor)
    );
    insert into closure values
    (1,1,0),
    (1,3,1),
    (1,4,2),
    (1,5,3),
    (2,2,0),
    (3,3,0),
    (3,4,1),
    (3,5,2),
    (4,4,0),
    (4,5,1),
    (5,5,0);
    

    このセットには、長さがゼロの「パス」も含まれていることに注意してください。つまり、メニュー項目はそれ自体の「親」です。

    これで、各メニュー項目mに参加できます 祖先のすべてのセットにamのパスに参加する デスカンダントです。そこから、メニュー項目oに戻ります これは祖先のセットに含まれており、orderにアクセスできます。 。

    GROUP_CONCAT()を使用して、orderから「ブレッドクラム」の文字列を作成します 祖先のチェーン内のそれぞれの文字列になります。これは、必要なメニュー順序を取得するために並べ替えることができる文字列になります。

    SELECT m.*, GROUP_CONCAT(o.`order` ORDER BY a.length DESC) AS breadcrumbs
    FROM menu AS m
    INNER JOIN closure AS a ON a.descendant = m.id
    INNER JOIN menu AS o ON a.ancestor = o.id
    GROUP BY m.id
    ORDER BY breadcrumbs;
    
    +----+----------+-------+-------------+
    | id | name     | order | breadcrumbs |
    +----+----------+-------+-------------+
    |  1 | Father1  |     0 | 0           |
    |  3 | Son      |     0 | 0,0         |
    |  4 | Child    |     1 | 0,0,1       |
    |  5 | Grandson |     2 | 0,0,1,2     |
    |  2 | Father2  |     1 | 1           |
    +----+----------+-------+-------------+
    

    ブレッドクラムは文字列として並べ替えられるため、orderがある場合は 2桁または3桁の数字の場合、不規則な結果が得られます。 orderを確認してください 数字はすべて同じ桁数です。

    別の方法として、パンくずリストの文字列を元のメニューテーブルに保存することもできます。

    ALTER TABLE menu ADD COLUMN breadcrumbs VARCHAR(255);
    UPDATE menu SET breadcrumbs = '0,0,1,2' WHERE id = 5;
    etc.
    

    次に、より簡単なクエリを実行できます:

    SELECT * FROM menu ORDER BY breadcrumbs;
    

    ただし、メニュー項目の順序を変更した場合は、影響を受けるすべてのブレッドクラム文字列を手動で再計算するのはあなた次第です。



    1. EasyPHPでphpmyadminを使用してSQLファイルをインポートする

    2. SQLServer2017にアップグレードする理由

    3. 11i/R12での多言語サポート

    4. Oracle列の自動変更タイムスタンプタイプはありますか?