Question

structure de table

id    |    message    |    reply_id
1     |    help me!   |    0
434   |    love to    |    1
852   |    didn't work |    434
0110  |    try this   |    852
2200  |    this wont  |    0
5465  |    done. :)   |    0110

J'ai un id « 852 » qui est milieu de menu arborescent, mais je veux tous les associés et suivant les lignes précédentes liées, donc je veux obtenir de tels résultats suivants:

  

me aider! > Amour> ne fonctionne pas> essayer> fait. :) (ce résultat montre que, après comme boucle de php, mais commence une boucle à partir de id démarreur 1 avec la réponse id 0.

NOTE:. Id 2200 ne montre pas dans le résultat, parce que sa ne fait pas partie du groupe

Était-ce utile?

La solution

Il existe plusieurs alternatives pour rendre l'information hiérarchique plus facile de travailler avec SQL:

  • Common Table Expressions (selon la norme SQL-2003) en charge les requêtes SQL récursives contre le type ID parent de données que vous utilisez. Jusqu'à présent, MySQL ne supporte pas cette fonctionnalité. PostgreSQL 8.4, Microsoft SQL Server et IBM DB2 sont des marques de SGBDR qui prennent en charge la syntaxe CTE. Oracle a également une extension exclusive à la syntaxe SQL qui prend en charge les requêtes récursives.

  • Sets emboîtés (la solution de gauche / droite qui @phantombrain mentionne) est une solution détaillée dans le livre de Joe Čelko "Les arbres et Hiérarchies dans SQL pour Smarties" et aussi dans de nombreux articles et blog messages affichés sur Internet.

  • Chemin Enumeration (aka Materialized chemin) stocke une chaîne dans chaque ligne de la hiérarchie de noter le chemin des ancêtres de cette ligne. Combinez cela avec les requêtes LIKE pour comparer la chaîne de chemin vers les chemins de descendants de ses ancêtres chemins.

  • Fermeture table (aka transitive fermeture Relation) utilise une seconde table pour stocker toutes les relations descendant ancêtres, non seulement le parent immédiat comme dans la conception que vous utilisez. De nombreux types de requêtes deviennent plus faciles une fois que vous avez tous les chemins stockés.

  • Des solutions hybrides existent également. Par exemple, stocker l'id du parent immédiat que vous faites, mais aussi la racine de l'arbre. Maintenant, vous pouvez obtenir toutes les autres lignes dans la même hiérarchie, les chercher dans le code d'application et trier l'arbre avec des structures de données classiques.

Autres conseils

ce sont des éléments Si l'on suppose de menu et pas quelque chose de très dynamique, comme un forum, je recommande un changement de schéma pour ajouter des valeurs à gauche et à droite pour chaque élément. Les ID entre les valeurs de gauche et de droite sont tous les enfants du nœud que vous interrogez. Ainsi, il est facile de faire une requête pour obtenir les valeurs de gauche / droite, et une deuxième requête pour obtenir les sous-éléments.

Voir http://www.sitepoint.com/print/hierarchical-data -database / pour plus d'informations

récursivité est la façon la plus élégante de le faire, mais je ne pense pas que mySql il prend en charge des fonctions personnalisées ou StoredProcedures. Je suggère une boucle dans une table temporaire ou variable de table pour obtenir vos identifiants, puis se joindre à la table et d'interroger les résultats retour. Je ne sais pas mySql très bien si ce n'est pas testé, mais quelque chose à cet effet.

CREATE TEMPORARY TABLE tbl (myid int, ViewOrder int); 
Set @ifoundID=IdYourLookingFor;
Set @iStartID=@ifoundID;
Set @iOrder=0;
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);

BEGIN --get the ones going up
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=reply_id FROM YourTable WHERE id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder-1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

Set @ifoundID=@iStartID;
BEGIN --get the ones going down
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=id FROM YourTable WHERE reply_id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder+1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

SELECT * FROM tbl INNER JOIN YourTable ON tbl.myid=YourTable.id ORDER BY ViewOrder

L'espoir qui aide

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top