我有以下树结构,使用嵌套的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', '', '');
谢谢!
答案 0 :(得分:0)
您的示例数据很难,因为您没有任何不是根节点的直接子节点的兄弟节点,但我将使用那里的内容:)
我认为你需要两个SQL调用 - 一个用于获取包含所选节点左/右值的所有节点,另一个用于使用前一个调用中的'父'左/右值抓住所选节点的兄弟姐妹
e.g。 获取包含目标节点左/右值的所有节点
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。这将返回所选节点的所有祖先,从顶层开始,然后向下移动到所选节点的直接父节点
第二个查询(兄弟姐妹)可以通过两种方式完成,具体取决于您是否要使用已返回的lft / rgt值(例如,从PHP中获取值),或者是否要在SQL中执行繁重的操作。在SQL中执行意味着查询更复杂,但您不需要除选定节点的id之外的任何数据
使用所选节点父节点的PHP值(在上一个查询中返回)
SELECT * FROM `exp_node_tree_1` WHERE (lft > ?) AND (rgt < ?) ORDER BY lft ASC
替换第一个?与父母的lft值,第二个?与父母的rgt值
第二种方法仅使用所选节点的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
希望这有帮助!