次の列を使用して、ミルのネストされたセットの階層タイプをセットアップしました。
テーブル名:
myset
列:
id, name, lft, rgt
ノードの親を決定するためのクエリを知っている人はいますか?
これを追跡するためにテーブルにparent_id列もあると便利な場所をいくつか読みましたが、冗長に見え、追加時にクエリが誤って実行された場合、ネストされたセットと同期しなくなる可能性があるようです/セット内の何かを削除/移動します。
次の列を使用して、ミルのネストされたセットの階層タイプをセットアップしました。
テーブル名:
myset
列:
id, name, lft, rgt
ノードの親を決定するためのクエリを知っている人はいますか?
これを追跡するためにテーブルにparent_id列もあると便利な場所をいくつか読みましたが、冗長に見え、追加時にクエリが誤って実行された場合、ネストされたセットと同期しなくなる可能性があるようです/セット内の何かを削除/移動します。
この質問を見てください。それはあなたのものに似ています。必要なクエリをそこに投稿しました。
SELECT title, (SELECT TOP 1 title
FROM tree t2
WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt
ORDER BY t2.rgt-t1.rgt ASC) AS parent
FROM tree t1
ORDER BY rgt-lft DESC
必要なものがあることを願っています。
次の表の場合:
+-------------+----------------------+-----+-----+
| category_id | name | lft | rgt |
+-------------+----------------------+-----+-----+
| 1 | ELECTRONICS | 1 | 20 |
| 2 | TELEVISIONS | 2 | 9 |
| 3 | TUBE | 3 | 4 |
| 4 | LCD | 5 | 6 |
| 5 | PLASMA | 7 | 8 |
| 6 | PORTABLE ELECTRONICS | 10 | 19 |
| 7 | MP3 PLAYERS | 11 | 14 |
| 8 | FLASH | 12 | 13 |
| 9 | CD PLAYERS | 15 | 16 |
| 10 | 2 WAY RADIOS | 17 | 18 |
出力が生成されます。
title | parent
----------------------------------------------
ELECTRONICS | NULL
PORTABLE ELECTRONICS | ELECTRONICS
TELEVISIONS | ELECTRONICS
MP3 PLAYERS | PORTABLE ELECTRONICS
FLASH | MP3 PLAYERS
CD PLAYERS | PORTABLE ELECTRONICS
2 WAY RADIOS | PORTABLE ELECTRONICS
TUBE | TELEVISIONS
LCD | TELEVISIONS
PLASMA | TELEVISIONS
TOPはMSSQLコマンドです。MySQLにはLIMITを使用してください。
SELECT title, (SELECT title
FROM tree t2
WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt
ORDER BY t2.rgt-t1.rgt ASC
LIMIT 1)
AS parent FROM tree t1
ORDER BY (rgt-lft) DESC
トリックを行う必要があります..
私を大いに助けてくれたこれらの回答に追加するだけで、
ノードの直接の親だけでなく、場合によってはノード チェーンの最上位レベルの親を見つける必要がありました。
以下をベースとして使用して、子から親の順序でアイテムを取得しました
SELECT parent.* FROM
nested_set node,
nested_set parent
WHERE (
node.set_left BETWEEN parent.set_left AND parent.set_right
)
AND node.set_id={CHILD_NODE_ID_HERE}
ORDER BY parent.set_right - parent.set_left
#LIMIT 1,1
LIMIT 1,1
次に、直接の親となる 2 番目の行のみをキャプチャするためにを追加するだけです
上記のクエリでは、ノード自体が最上位の親である場合、直接の親を持たないためLIMIT 1,1
、空の結果セットを返す必要があることにも注意してください。
最上位の親を取得するために、 order by 句を逆にし、ノード自体が最上位の親であるかどうかのチェックを含め、結果を最初の行に制限しました
SELECT parent.* AS top_level_right FROM
nested_set node,
nested_set parent
WHERE (
node.set_left >= parent.set_left
AND node.set_left <= parent.set_right
)
AND node.set_id={CHILD_NODE_ID_HERE}
ORDER BY parent.set_left - parent.set_right
LIMIT 1
最後のクエリでは、>= <=
演算子を使用して、選択した範囲が最上位の親でもある場合に子ノードを包含するようにしました
Lucasz のクエリに問題がありました。私のバージョンの mysql は TOP コマンドを理解できませんでした。代わりに LIMIT を使用する必要がありました。これが修正されたコードです。
SELECT
`id`,
(SELECT
`id`
FROM
`[*** YOUR TABLE ***]` AS `t2`
WHERE
`t2`.`left_id` < `t1`.`left_id`AND
`t2`.`right_id` > `t1`.`right_id`
ORDER BY
`t2`.`right_id`-`t1`.`right_id`ASC
LIMIT
1) AS `parent`
FROM
`[*** YOUR TABLE ***]` AS `t1`
WHERE
`t1`.`id` = [*** ID OF THE NODE WHOS PARENT YOU WISH TO LOOKUP ***]
ORDER BY
`right_id`-`left_id` DESC
明らかに、必要に応じて [ ] 内のものを変更してください。[ ] も削除します。このクエリは 1 行のみを返します。そのようです...
id parent
7 3
SELECT parent.name
FROM myset AS node, myset AS parent
WHERE parent.lft < node.lft
AND parent.rgt > node.rgt
AND node.id = {YOUR CATEGORY ID}
ORDER BY ( parent.rgt - parent.lft ) ASC LIMIT 1;
select * from myset
where lft < :lftOfCurrent and rgt > :lftOfCurrent
order lft desc
limit 1
order/limit ではなく max を使用できます。データベースによっては、結果を 1 行に制限するために別のキーワードが必要になる場合があります。データベースが排他的セットを返す場合、MySQL は返さない < と > ではなく、Between が機能します。
spankmaster79のコードは完全に間違っていたわけではありません。私は彼のコードを変更しました、そしてそれは働きました。
SELECT parent . * FROM Nested_Category AS node, Nested_Category AS parent
enter code hereWHERE node.leftSide
BETWEEN parent.leftSide
AND parent.rightSide
AND node.id ='Enter the Node ID'
ORDER BY (
parent.rightSide - parent.leftSide
)
LIMIT 1 , 1
すべての祖先が返されます
SELECT id FROM thetable
WHERE x BETWEEN lft and rgt;
したがって、直接の親は、lft と rgt の差が最も小さい祖先です。
SELECT id FROM thetable
WHERE x BETWEEN lft and rgt
ORDER BY (rgt-lft)
LIMIT 1