ここのサイトポントの写真のように、標準のmpttツリーテーブルがあります。ただし、選択したノードに基づいてサブツリー全体を取得する良い方法を見つけることはできません。
例 (リンクされたページから): 誰かが「チェリー」を選択した場合、ツリーがメニューであると想像してください。「フルーツ」ノードからすべてのアイテムを下に取得したいと考えています。
したがって、次を使用して最終的な親行(不要なルートを除く)を取得できます
SELECT lft, rgt FROM menu_items
WHERE lft < (SELECT lft FROM menu_items WHERE id = 'Cherry')
AND rgt > (SELECT rgt FROM menu_items WHERE id = 'Cherry')
AND lft > 1
ORDER BY lft ASC LIMIT 1
これは、3つのSELECTを使用したかなりお粗末なSQLだと思いますが、lftとrgtの間のすべてのノードを取得するためにさらにクエリで使用できるlftとrgtを取得します-したがって、「Cherry」が含まれるサブツリーを取得します.
私はそれをすべて1つのクエリで実行するための基礎として使用しました-その結果、この忌まわしさが生まれました:
SELECT * FROM menu_items
WHERE lft BETWEEN
(SELECT lft FROM menu_items
WHERE lft < (SELECT lft FROM menu_items WHERE id = 'Cherry')
AND rgt > (SELECT rgt FROM menu_items WHERE id = 'Cherry')
AND lft > 1
ORDER BY lft ASC LIMIT 1)
AND
(SELECT rgt FROM menu_items
WHERE lft < (SELECT lft FROM menu_items WHERE id = 'Cherry')
AND rgt > (SELECT rgt FROM menu_items WHERE id = 'Cherry')
AND lft > 1
ORDER BY lft ASC LIMIT 1)
ORDER BY lft ASC;
それは私にはかなり厄介なようです - 7つの SELECT !
これをエレガントに実行できますか (できれば 1 つのクエリで実行できますが、それほど重要ではありません - 読みやすさ > 単一のクエリ) ?
ところで - lft と rgt は、MPTT 番号付けのための私のフィールド名です
編集:::実験の後、私の不器用なSQLは私が望むことをしないことに気付きました。ルートより 2 レベル以上深いノードでのみ機能します。
私の質問は次のとおりです。投稿の上部にリンクされている図を参照してください-ユーザーがサブツリーのリーフまたは親ノードを「選択」した場合、ルートを含まないサブツリー全体を取得する必要があります。
したがって、ユーザーが「Cherry」、「Banana」、「Red」、「Yellow」、または「Fruit」を選択した場合、「Fruit」サブツリー全体が必要です。