11

次の列を使用して、ミルのネストされたセットの階層タイプをセットアップしました。

テーブル名:

myset

列:

id, name, lft, rgt

ノードのを決定するためのクエリを知っている人はいますか?

これを追跡するためにテーブルにparent_id列もあると便利な場所をいくつか読みましたが、冗長に見え、追加時にクエリが誤って実行された場合、ネストされたセットと同期しなくなる可能性があるようです/セット内の何かを削除/移動します。

4

8 に答える 8

21

この質問を見てください。それはあなたのものに似ています。必要なクエリをそこに投稿しました。

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
于 2009-10-21T18:10:47.160 に答える
17

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

トリックを行う必要があります..

于 2010-08-23T14:59:56.207 に答える
3

私を大いに助けてくれたこれらの回答に追加するだけで、

ノードの直接の親だけでなく、場合によってはノード チェーンの最上位レベルの親を見つける必要がありました。

以下をベースとして使用して、子から親の順序でアイテムを取得しました

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

最後のクエリでは、>= <=演算子を使用して、選択した範囲が最上位の親でもある場合に子ノードを包含するようにしました

于 2013-03-29T00:12:27.343 に答える
2

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
于 2010-01-04T03:22:04.020 に答える
1
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;
于 2013-06-11T18:25:21.287 に答える
1
select * from myset
  where lft < :lftOfCurrent and rgt > :lftOfCurrent
  order lft desc
  limit 1

order/limit ではなく max を使用できます。データベースによっては、結果を 1 行に制限するために別のキーワードが必要になる場合があります。データベースが排他的セットを返す場合、MySQL は返さない < と > ではなく、Between が機能します。

于 2011-06-08T17:53:00.467 に答える
0

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
于 2010-12-17T10:54:31.630 に答える
0

すべての祖先が返されます

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
于 2009-10-21T18:13:34.320 に答える