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

ツリーのアイテム数のクエリ

    これらの制約を考えると、方法はありません。このような場合は、すべてを取得します。 ツリーを作成して「ヒル」クライアント側を構築するか、特定のケースで最もパフォーマンスが高いものなら何でも再帰クエリを実行します。

    固定数の階層レベルを持つという追加の制約があります 、複数のJOINを使用してこれを行うことができます。

    一般的なケースでは、これらの制約を克服できるようにするために、いくつかの構造変更があります。実際には、「これは私のテーブル構造です」という制約を緩和して、フィールドを追加できるようにします。

    たとえば、ノード構造をleft_idで補足できます。 値を指定し、ツリーの深さ優先にアクセスするときに、すべてのノードIDが順番に並んでいることを確認します。

    1 --- 2 -+- 3 -+- 4
             |     |
             |     +- 5
             +- 6 --- 7
    

    この場合、ノード3は値「5」を格納し、ノード6は値「7」を格納し、ノード2も値「7」を格納します。 各ノードは、子のLeftIDと自身のIDの間の最大値をLeftIDに格納します

    したがって、子のないノードのLeftIDはIDと同じです。ノード1はLeftID7を持ちます。これはLeftIDが2であり、6から取得したためです。

    この状況では、カウント シーケンスに穴がない場合、ノードは簡単です。ノードのすべての子孫は、IDが開始ノードのIDとそのLeftIDの間にあるノードです。葉は、LeftIDがIDと等しいことで識別されます。

    したがって、「ノードID17から派生するすべてのリーフ」は

    になります。

    SELECTchild。*FROMtable AS parentJOIN table AS childON(child.id> parent.id AND child.id <=parent.leftid)/*子孫/ WHERE child.id =child.leftid / リーフ/AND parent.id =17; / 親は17歳です

    この構造は、整理と分岐を実行できるようにする場合に維持するのが面倒です。これは、整理のポイントから分岐のポイントまでのすべてのノードと、移動されたノードの番号を変更する必要があるためです。

    カウントのみに関心がある場合のもう1つの可能性は、子カウンターを保持することです。これは、繰り返し更新し、すべての葉を選択し、それらのカウンターを0に設定することで維持できます(LEFT JOINを介して葉を識別します)。次に、NULLカウンターを持つすべての親で、NULL以外のカウンターを持つ子があり、カウンターをSUM()に更新します。 子供のカウンターとCOUNT()の数 子供自身の;すべてのノードにNULL以外のカウンターがあるため、更新された行の数がゼロになるまで続行します。整理して分岐した後、すべてのカウンターをNULLに設定して繰り返します。

    この最後のアプローチでは、階層レベルごとにリフレクティブ結合が必要です。



    1. PythonDateTime文字列の整数ミリ秒への変換

    2. PHPエラーを使用してMySQLデータベースに保存されているPDFファイルを表示する

    3. MariaDBでのCONCAT_WS()のしくみ

    4. PG ::UndefinedTable:エラー:正しいRailsの命名と規則で関係が存在しません