Il n'y a pas de requête SQL unique qui peut vous apporter des résultats classés comme vous l'attendez en fonction de cette structure de table.
Il existe deux manières de résoudre le problème :
-
Utilisez une logique d'application externe (en dehors de la base de données) pour effectuer des appels récursifs qui découvriront les enfants de chaque catégorie et créeront l'arborescence dans l'application.
-
Utilisez l'un des algorithmes pour stocker les données d'arbre dans une base de données relationnelle. L'un de ces algorithmes est appelé
Modified Preorder Tree Traversal
ou simplement MPTT.
En supposant que nous utilisons les colonnes lft
et rgt
pour maintenir les index gauche/droite en parcours, lorsque vous insérez une nouvelle catégorie vous devrez :
-
Obtenir les informations sur la catégorie parent par ID :
SELECT lft,rgt FROM tbl_categories WHERE categoryId=5
Supposons par exemple que la catégorie parente aitlft=7
etrgt=10
(dans ce cas, il a déjà un enfant) -
Faites de la place pour une nouvelle entrée - décalez tous les enregistrements de 2 (1 pour lft et 1 pour rgt) :
UPDATE tbl_categories SET rgt=rgt+2 WHERE rgt>=10 ORDER BY rgt DESC
UPDATE tbl_categories SET lft=lft+2 WHERE lft>=10 ORDER BY lft DESC
Notez ici ORDER
descendant. Comme lft
et rgt
sont censés être uniques, il est conseillé de faire un UNIQUE
contrainte sur eux, puis l'ordre décroissant dans la mise à jour est nécessaire pour éviter les erreurs de clé en double.
-
Définir
lft=<former parent rgt>
etrgt=<former parent rgt +1>
et insérez un nouvel enregistrement...INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Vous pouvez trouver des exemples plus détaillés avec du code si vous recherchez MPTT PHP MySQL
. Il existe pas mal de tutoriels sur ce sujet.