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

クエリを実行して、子レコードを含む親レコードを取得し、続いてmysqlの次の親子レコードを取得します

    ここで提案するソリューションは、マテリアライズドパスの概念を使用しています。以下は、サンプルデータを使用したマテリアライズドパスの例です。マテリアライズドパスの概念を理解するのに役立つことを願っています:

    +----+--------------------------+----------+------------------+
    | ID |           Name           | ParentID | MaterializedPath |
    +----+--------------------------+----------+------------------+
    |  1 | Parent 1                 |        0 | 1                |
    |  2 | Parent 2                 |        0 | 2                |
    |  4 | Parent 2 Child 1         |        2 | 2.4              |
    |  6 | Parent 2 Child 1 Child 1 |        4 | 2.4.6            |
    |  7 | Parent 2 Child 1 Child 2 |        4 | 2.4.7            |
    |  3 | Parent 1 Child 1         |        1 | 1.3              |
    |  5 | Parent 1 Child 1 Child   |        3 | 1.3.5            |
    +----+--------------------------+----------+------------------+
    

    各ノードN マテリアライズされたパスがあります。このパスは、ルートノードからノードNに移動する方法を示します。 。ノードIDを連結してビルドできます。たとえば、ノード5に到達するには ルートノードから開始して、ノード1にアクセスします 、ノード3 、およびノー​​ド5 、ノード5 マテリアライズドパスは1.3.5

    偶然にも、あなたが探している注文は、具体化されたパスによって注文を達成することができます。

    前の例では、マテリアライズされたパスは文字列を連結するbuitですが、いくつかの理由からバイナリ連結を好みます。

    マテリアライズされたパスを構築するには、次の再帰CTEが必要です。

    CREATE TABLE Tree
    (
        ID int NOT NULL CONSTRAINT PK_Tree PRIMARY KEY, 
        Name nvarchar(250) NOT NULL,
        ParentID int NOT NULL,
    )
    
    INSERT INTO Tree(ID, Name, ParentID) VALUES
    (1, 'Parent 1', 0),
    (2, 'Parent 2', 0),
    (3, 'Parent 1 Child 1', 1),
    (4, 'Parent 2 Child 1', 2),
    (5, 'Parent 1 Child 1 Child', 3),
    (6, 'Parent 2 Child 1 Child 1', 4),
    (7, 'Parent 2 Child 1 Child 2', 4)
    
    GO
    WITH T AS
    (
        SELECT
            N.ID, N.Name, N.ParentID, CAST(N.ID AS varbinary(512)) AS MaterializedPath
        FROM
            Tree N
        WHERE
            N.ParentID = 0
    
        UNION ALL
    
        SELECT
            N.ID, N.Name, N.ParentID, CAST( T.MaterializedPath + CAST(N.ID AS binary(4)) AS varbinary(512) ) AS MaterializedPath
        FROM
            Tree N INNER JOIN T
                ON N.ParentID = T.ID
    
    )
    SELECT *
    FROM T
    ORDER BY T.MaterializedPath
    

    結果:

    +----+--------------------------+----------+----------------------------+
    | ID |           Name           | ParentID |      MaterializedPath      |
    +----+--------------------------+----------+----------------------------+
    |  1 | Parent 1                 |        0 | 0x00000001                 |
    |  3 | Parent 1 Child 1         |        1 | 0x0000000100000003         |
    |  5 | Parent 1 Child 1 Child   |        3 | 0x000000010000000300000005 |
    |  2 | Parent 2                 |        0 | 0x00000002                 |
    |  4 | Parent 2 Child 1         |        2 | 0x0000000200000004         |
    |  6 | Parent 2 Child 1 Child 1 |        4 | 0x000000020000000400000006 |
    |  7 | Parent 2 Child 1 Child 2 |        4 | 0x000000020000000400000007 |
    +----+--------------------------+----------+----------------------------+
    

    上記の再帰CTEは、ルートノードから始まります。ルートノードのマテリアライズドパスの計算は簡単です。これはノード自体のIDです。次の反復で、CTEはルートノードをその子ノードに結合します。子ノードのマテリアライズドパスCN 親ノードPNのマテリアライズドパスを連結したものです およびノー​​ドCNのID 。後続の反復は、リーフノードに到達するまでツリーの1レベル下に進みます。




    1. 複数の1対1を作成する方法

    2. オートコンプリートのためにMYSQLの会社名とPHPのあいまい一致を行うにはどうすればよいですか?

    3. 一時テーブルのメタデータをフェッチしたくないSSISパッケージ

    4. PostgreSQLでのAcosh()のしくみ