2

lft と rgt の値を持つネストされたセットを使用して、次のツリー構造があります。

node
    node
        node
    node
        node (selected)
        node
node
node
    node

ツリーが展開され、選択したノードのパスにのみ表示され、関係のないノードが折りたたまれたり非表示になったりするようにナビゲーションを構築したいと思います。

上記の方法を使用すると、ツリーは次のように出力されます。

node
    node
    node
        node (selected)
        node
node
node

これはphp/mysqlを使用して可能ですか? SQLの達人がクエリの作成を手伝ってくれるなら、私は最も感謝しています.?

レベルごとに追加のクエリが必要かどうかは気にしません。おそらく、せいぜい 4 または 5 レベルの深さになるだけです...

ノード テーブルの概要:

--
-- Table structure for table `exp_node_tree_1`
--

CREATE TABLE `exp_node_tree_1` (
  `node_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `lft` mediumint(8) unsigned DEFAULT NULL,
  `rgt` mediumint(8) unsigned DEFAULT NULL,
  `moved` tinyint(1) NOT NULL,
  `label` varchar(255) DEFAULT NULL,
  `entry_id` int(10) DEFAULT NULL,
  `template_path` varchar(255) DEFAULT NULL,
  `custom_url` varchar(250) DEFAULT NULL,
  `extra` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`node_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;

--
-- Dumping data for table `exp_node_tree_1`
--

INSERT INTO `exp_node_tree_1` VALUES(1, 1, 12, 0, 'Home', 1, '0', '/', '');
INSERT INTO `exp_node_tree_1` VALUES(5, 10, 11, 0, 'About Us', 2, '4', '', '');
INSERT INTO `exp_node_tree_1` VALUES(6, 6, 9, 0, 'Team', 3, '5', '', '');
INSERT INTO `exp_node_tree_1` VALUES(7, 3, 4, 0, 'Contact Us', 4, '4', '', '');
INSERT INTO `exp_node_tree_1` VALUES(8, 7, 8, 0, 'Awards', 5, '5', '', '');
INSERT INTO `exp_node_tree_1` VALUES(10, 2, 5, 0, 'New Page', 6, '4', '', '');

ありがとうございました!

4

1 に答える 1

0

ルートノードの直接の子ではない兄弟ノードがないことを考えると、サンプルデータは難しくなりますが、そこにあるものを使用して作業します:)

2つのSQL呼び出しが必要になると思います。1つは選択したノードの左/右の値を含むすべてのノードを取得し、もう1つは前の呼び出しの「親」の左/右の値を使用して兄弟を取得します。選択したノードの

例:ターゲットノードの左/右の値を含むすべてのノードを取得します

SELECT e.* FROM exp_node_tree_1 as e, (SELECT lft, rgt FROM exp_node_tree_1 WHERE node_id = ?) AS tbl WHERE (e.lft < tbl.lft) and (e.rgt > tbl.rgt) ORDER BY e.lft ASC

?を交換してください 選択したノードのnode_idを使用します。これにより、選択したノードのすべての祖先が返されます。トップレベルから始まり、選択したノードの直接の親に至るまでです。

2番目のクエリ(兄弟)は、すでに返されたlft / rgt値を使用するか(PHPから値を取得するなど)、SQLで手間のかかる作業を行うかどうかに応じて、2つの方法で実行できます。SQLで実行すると、クエリがより複雑になりますが、選択したノードのID以外のデータは必要ありません。

選択したノードの親からのPHP値を使用する(前のクエリで返された)

SELECT * FROM `exp_node_tree_1` WHERE (lft > ?) AND (rgt < ?) ORDER BY lft ASC

最初の?親のlft値、および2番目の?親のrgt値を使用

2番目の方法では、選択したノードのnode_idのみを使用します

select s.* FROM exp_node_tree_1 as s, (SELECT e.lft, e.rgt FROM exp_node_tree_1 as e, (SELECT lft, rgt FROM exp_node_tree_1 WHERE node_id = ?) AS tbl WHERE (e.lft < tbl.lft) and (e.rgt > tbl.rgt) ORDER BY e.lft DESC LIMIT 1) as parent WHERE (s.lft > parent.lft) AND (s.rgt < parent.rgt) ORDER BY s.lft ASC

私が言ったように-もう少し複雑です。?を交換してください 選択したノードのnode_idを使用

お役に立てれば!

于 2010-11-28T13:26:27.630 に答える