最近、私はNested Set Modelの駄菓を使っています。私はちょうどすべての便利な操作と表示のためのクエリの設計を楽しんでいます。私が執着していることの1つは、直下の子供を選択する方法です(ノード子供、それ以上の子孫ではありません!)。ノードの子を照会する簡単な方法はありますか?
私は方法を知っていますが、それには管理できない量のSQLが含まれています。より簡単な解決策があると確信しています。
最近、私はNested Set Modelの駄菓を使っています。私はちょうどすべての便利な操作と表示のためのクエリの設計を楽しんでいます。私が執着していることの1つは、直下の子供を選択する方法です(ノード子供、それ以上の子孫ではありません!)。ノードの子を照会する簡単な方法はありますか?
私は方法を知っていますが、それには管理できない量のSQLが含まれています。より簡単な解決策があると確信しています。
投稿した記事を読んだことがありますか?それは私が隣接リストと入れ子になったセットを組み合わせているが、私は何をすべきか(これは浮気された)
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;
の「ノードの直接の部下を探す」の見出しの下だ - 私は、テーブル内の「PARENT_ID」を埋め込みます私はノードの子供たちに簡単に質問することができます。
これは、サブクエリや親カラムの冗長性を持たないと簡単に実行できるはずです。例えば、与えられた親の左と右のは、既に知られている:
あるSELECT child.id
FROM nodes AS child
LEFT JOIN nodes AS ancestor ON
ancestor.left BETWEEN @parentleft+1 AND @parentright-1 AND
child.left BETWEEN ancestor.left+1 AND ancestor.right-1
WHERE
child.left BETWEEN @parentleft+1 AND @parentright-1 AND
ancestor.id IS NULL
、「問題のノードのすべての子孫からは、自分自身とノードの間には祖先を持つものを選びます」。
パフォーマンス、この1つまたは受け入れられたポストの中で、どちらの方が優れているのでしょうか。しかし、両方のソリューションが機能します。これはもう少しコンパクトに見えます。 – andreas
非常に大きなツリーの場合、MySQLではパフォーマンスが悪く、SQLサーバーではパフォーマンスが悪いことがわかりました。ネストループをデータベースで実行する必要があるためです。すべての子孫を取得するだけでコードを変更した後、アプリケーションコード内の子のみにプルーニングしました。 – user393274
@andreasこれは受け入れられた答えと非常によく似ていますが、違いは、子供を数えて1人の子供にフィルタリングするのではなく、祖先がNULLかどうかを見てフィルタリングすることです。カウントステップ)。それは速くなければならないが、私はそれをテストしていない。 – Ariel
THIS ONEは
ユーザー "bobinceは" ほとんどそれを持っていたより良く、小さくなっています。私はそれを理解して、MySQLの経験がもう少し多かったので、私のために働くようにしました。しかし、なぜ私はbobinceの答えが人々を恐れているのかを知ることができます。彼の質問は不完全です。まず、mysql変数にparent_leftとparent_rightを選択する必要があります。以下
2つのクエリは、あなたの左の列が右のカラムがrgt
命名され、lft
という名前の、そしてあなたの主キーがid
命名されていることをされ、あなたのテーブルがtree
命名されていることを前提としています。これらの値を必要に応じて変更します。また、最初のselectステートメントを調べます。私はノード5の直下の子孫を探していることがわかります。番号5を変更して、必要なノードの子を探す。
私は個人的にはこれまでよりも洗練された、よりセクシーで、より効率的なクエリだと思います。
SELECT `lft`, `rgt` INTO @parent_left, @parent_right FROM efm_files WHERE `id` = 5;
SELECT `child`.`id`
FROM `tree` AS `child`
LEFT JOIN `tree` AS `ancestor` ON
`ancestor`.`lft` BETWEEN @parent_left+1 AND @parent_right-1 AND
`child`.`lft` BETWEEN `ancestor`.`lft`+1 AND `ancestor`.`rgt`-1
WHERE
`child`.`lft` BETWEEN @parent_left+1 AND @parent_right-1 AND
`ancestor`.`id` IS NULL
'efm_files'とは何ですか? – Madbreaks
efm_filesは、mysqlデータベース内のテーブルの名前です。データベースの独自のテーブル名に置き換えます。 – mrbinky3000
iはネクロポスト、 をやっイムを知っているが、ここで私の意見です。
ネストしたセットに「深度」列を含めないのはなぜですか? 奥行きの列は項目の「レベル」を示します。アイテムの即時チャイルズを選択するので、
は、ちょうど
select c.*
from tree as p
join tree as c on (c.left > p.left and c.right < p.right and c.depth = p.dept + 1) where p.id = @parentID
厳密に言えば、これはもはやネストされたセットではないため、階層モデルの組み合わせです。そして、しばしば問題を解決するためにモデルを変更することは選択肢ではありません。 – Madbreaks
を行う私も、深欄で行くと思います。しかし、私はWikipedia linkは、選択した答えと一緒に答えの良い最小化バージョンを持っていた
SELECT Child.Node, Child.LEFT, Child.RIGHT
FROM Tree AS Child, Tree AS Parent
WHERE
Child.Depth = Parent.Depth + 1
AND Child.LEFT > Parent.LEFT
AND Child.RIGHT < Parent.RIGHT
AND Parent.LEFT = 1 -- Given Parent Node Left Index
左右のIDと共に*追加の*深さの列が必要であることに注意してください。 – Youngjae
使用しています。
SELECT DISTINCT Child.Name
FROM ModelTable AS Child, ModelTable AS Parent
WHERE Parent.Lft < Child.Lft AND Parent.Rgt > Child.Rgt -- associate Child Nodes with ancestors
GROUP BY Child.Name
HAVING MAX(Parent.Lft) = @parentId -- Subset for those with the given Parent Node as the nearest ancestor
そして、あなたがたのうち、LINQのとそれを表現しようとすると、リンクをクリックしてください:https://stackoverflow.com/a/25594386/361100
ハ「...私は、隣接リスト...と、ネストされたセットを組み合わせました」!それは私がやっていることです。私はadjに加入する。 Joe Celkoによるクエリに基づいたリストビュー。それはひどいコードのようです。リンクされた記事のソリューションでさえも...冗長です。 – Metaphile
つまり、ノードの子孫を_all_を選択して比較することを意味します。 SELECT * ノードから どこのノードか。左上のBETWEENのparentLeftBoundとparentRightBound; – Metaphile
まあ、 "child_view"は非常にシンプルです、SELECT * FROMノードwhere parent_id = 123456:D –