Det finns ingen enskild SQL-fråga som kan ge dig resultat ordnade som du förväntar dig baserat på den här tabellstrukturen.
Det finns två sätt att lösa problemet:
-
Använd extern applikationslogik (utanför DB) för att göra rekursiva anrop som kommer att upptäcka barn i varje kategori och bygga trädet i applikationen.
-
Använd en av algoritmerna för att lagra träddata i en relationsdatabas. En av sådana algoritmer heter
Modified Preorder Tree Traversal
eller helt enkelt MPTT.
Förutsatt att vi använder kolumner lft
och rgt
för att bibehålla vänster/höger index i korsning, när du infogar en ny kategori måste du:
-
Få information om överordnad kategori efter Id:
SELECT lft,rgt FROM tbl_categories WHERE categoryId=5
Låt oss för ett exempel anta att den överordnade kategorin hadelft=7
ochrgt=10
(i det här fallet har den redan ett barn) -
Gör plats för en ny post - flytta alla poster med 2 (1 för lft och 1 för 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
Notera här ORDER
nedåtgående. Som lft
och rgt
antas vara unika, rekommenderas det att göra en UNIQUE
begränsning på dem, och sedan behövs fallande ordning i uppdatering för att förhindra dubbla nyckelfel.
-
Ställ in
lft=<former parent rgt>
ochrgt=<former parent rgt +1>
och infoga en ny post...INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Du kan hitta mer detaljerade exempel med kod om du söker efter MPTT PHP MySQL
. Det finns en hel del handledningar om detta ämne.