2010-04-07 3 views
2

J'ai la structure arborescente suivante en utilisant des ensembles imbriqués avec des valeurs rgt & lft.construire une navigation avec des ensembles imbriqués, à partir du nœud sélectionné

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

Je souhaite construire une navigation de sorte que l'arbre est étendu, pour le chemin d'accès du noeud sélectionné, et des noeuds non pertinents sont affaissées/caché.

En utilisant la méthode ci-dessus, l'arbre serait émis comme suit:

node 
    node 
    node 
     node (selected) 
     node 
node 
node 

est-ce possible en utilisant php/mysql? Si des gourous SQL peuvent aider à construire une requête, je serais très reconnaissant.

Cela ne me dérange pas si je besoin d'une requête supplémentaire par niveau, son probablement va être 4 ou 5 niveaux de profondeur au plus ...

Vue d'ensemble de la table nœuds:

-- 
-- 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', '', ''); 

Merci!

+0

S'il vous plaît montrer le contenu du tableau SQL que vous avez, cela aiderait beaucoup. – Tomalak

+0

Je viens de poster le vidage sql, merci –

+0

Est-ce un must que vous devez utiliser un arbre?Je voudrais juste mettre un parent_id et renvoyer l'élément parent c'est plus simple et comme vous n'avez que 10-20 enregistrements dans le tableau entier, je ne vois aucun point d'une structure aussi complexe. –

Répondre

0

Vos données de l'échantillon rend difficile, étant donné que vous n'avez pas encore entre frères et nœuds qui ne sont pas des enfants directs du nœud racine, mais je vais travailler avec ce qui est là :)

I'D pense que vous aurez besoin de deux appels SQL - un pour récupérer tous les nœuds qui contiennent les valeurs gauche/droite du nœud sélectionné, et un pour utiliser les valeurs gauche/droite 'parent' de l'appel précédent pour récupérer les frères et soeurs de votre sélection noeud

par exemple Grab tous les noeuds qui contiennent les valeurs de gauche/droite de votre noeud cible

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 

Raccrochez le? avec le node_id du noeud sélectionné. Cela renvoie tous les ancêtres du nœud sélectionné, en commençant par le niveau supérieur et en descendant vers le parent direct du nœud sélectionné

La deuxième requête (frères et sœurs) peut être effectuée de deux façons, en fonction de l'utilisation que vous voulez faire du nœud./rgt valeurs déjà retournées (par exemple en saisissant les valeurs de PHP), ou si vous voulez faire le gros du travail en SQL. Le faire dans SQL signifie que la requête est plus complexe, mais vous n'avez pas besoin de données autres que l'ID de nœud sélectionné

En utilisant les valeurs PHP des parents du nœud sélectionné (retourné dans la requête précédente)

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

Remplacer le premier? avec la valeur lft du parent, et le second? avec la valeur de TGB du parent

La deuxième méthode utilise uniquement le id_noeud du noeud sélectionné

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 

Comme je l'ai déjà dit - un peu plus complexe. Remplace le ? avec le noeud sélectionné node_id

Espérons que cela aide!

Questions connexes