6

私は、ネストされたセット モデルを使用して表現される MySQL のツリー構造を使用しています。

SQL の専門家の何人かが SELECT クエリの作成を手伝ってくれることを願っています。

LIKE を使用して一連のノードを照合できるようにしたいと考えています。一致するノードごとに、そのノードの先祖のコンマ区切りリストと、そのノードの直接の子のコンマ区切りリストも必要です。

どこから始めればいいのかよくわかりません-そのようなことが単一のクエリで可能である場合。(現在、ループ内のクエリでこれを達成しています。)私が望んでいるのは、次のような結果セットです....

文字列「qu」から始めて、テーブル「Body」を照会すると...

Node      | Parent Nodes               | Immediate Children
Quads       Leg, Lower Body, Muslces     Vastus Lateralus, Vastus Medialis, Rectus Femoris
Obliques    Core, Trunk, Muscles         Inner obliques, outer obliques

クエリをループせずにこれを達成する方法についての提案は大歓迎です。

4

4 に答える 4

0

1つのクエリで?私は気にしません。SQL は恐ろしく、おそらくそれほど効率的ではありません。各ビットを論理的なより小さなクエリに分割します。最初に一致するすべてのノードを見つけ、次にそれらのそれぞれについて、必要な追加情報を見つけます。

于 2010-02-23T14:44:43.273 に答える
0

あなたが何を望んでいるかは100%わかりませんが、正しく理解できれば、正規化されたデータベーススキーマとサブクエリを使用してこれを実現できます。

例えば:

テーブル「nodes」 テーブル「node_parents」

「nodes」テーブルはすべてのノードを格納し、「node_parents」は異なるノード間の関係をマップします。

したがって、LIKE 特定のノードを選択すると、node_parents からすべての親と子を取得できます。

結合またはサブクエリを使用して追加情報を取得できます。

于 2010-02-23T14:47:08.310 に答える
0

これは悪くて汚いというニックフに同意しますが、それでも楽しいので、ここに行きます:

SELECT     base.left_id, base.ancestors, 
           GROUP_CONCAT(children.left_id) children
FROM       (
            SELECT     base.left_id
            ,          GROUP_CONCAT(ancestors.left_id) ancestors
            FROM       nested_set   base
            LEFT JOIN  nested_set   ancestors
            ON         base.left_id     BETWEEN ancestors.left_id 
                                            AND ancestors.right_id
            WHERE      base.name  LIKE '%criteria%'
            GROUP BY   base.left_id
           ) base                                    
LEFT JOIN  nested_set   children
ON         children.left_id BETWEEN base.left_id 
                                AND base.right_id
LEFT JOIN  nested_set   inbetween
ON         inbetween.left_id BETWEEN base.left_id 
                                AND base.right_id
AND        children.left_id  BETWEEN inbetween.left_id 
                                AND inbetween.right_id     
WHERE      inbetween.left_id IS NULL
GROUP BY   base.left_id

基本的に、トリックは 2 つのステップでそれを解決することです。まず、祖先の問題を解決し、祖先をリストに押しつぶしてから、この結果を使用して子供のために解決します。

祖先の部分は比較的簡単です。それは、私のソリューションの from 句のサブクエリです。子供はちょっと大変です。これは、すべての子孫を取得し、基本ノードと子孫の間にノードが存在しないことを要求することで機能します。これにより、基本的に子孫は子のみに制限されます。

これを解決するために、この戦略には他のバリエーションがあります。たとえば、最初に子を実行し、SELECTリスト内のサブクエリを使用して祖先を解決できます。

于 2010-02-23T14:48:05.677 に答える
0

この質問は、他の投稿で予想したよりもはるかに難しいですが、最初の投稿者の回答には同意しません。

単一のクエリでそれが可能であると確信しています。

SUBQUERIES と selects を使用する必要があります。隣接リスト モデルに関する mySQL Web サイトの非常に優れたデモを見たことがありますか。

「ノード」に対して LIKE を使用できるため、SQL クエリにサブクエリを使用して、すべての親と親を取得できます。私がこのようなことをした私のクエリの1つは、絶対に大規模でした! しかし、それはうまくいきました。

見てみましょう: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

これは、直接の子がどのように見つかるかを示す小さなコード スニペットです。

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
    nested_category AS parent,
    nested_category AS sub_parent,
    (
        SELECT node.name, (COUNT(parent.name) - 1) AS depth
        FROM nested_category AS node,
        nested_category AS parent
        WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.name = 'PORTABLE ELECTRONICS'
        GROUP BY node.name
        ORDER BY node.lft
    )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
    AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
    AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft
于 2010-02-23T14:48:07.213 に答える