sql >> Databasteknik >  >> RDS >> Mysql

Mysql-fråga som returnerar kategoriträd

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:

  1. 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.

  2. 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:

  1. 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 hade lft=7 och rgt=10 (i det här fallet har den redan ett barn)

  2. 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.

  1. Ställ in lft=<former parent rgt> och rgt=<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.



  1. Hur man snabbt sorterar om en MySQL-tabell efter en av kolumnerna?

  2. Hur kan jag lägga till en främmande nyckel när jag skapar en ny tabell?

  3. Hur lagrar man obegränsat antal tecken i Oracle 11g?

  4. Det är möjligt att infoga data i två olika tabeller i mysql med en insert-fråga php?