sql >> Database >  >> RDS >> Mysql

Mysql-query die de categorieboom retourneert

Er is geen enkele SQL-query die u resultaten kan opleveren die zijn geordend zoals u verwacht op basis van deze tabelstructuur.

Er zijn twee manieren om het probleem op te lossen:

  1. Gebruik externe applicatielogica (buiten DB) om recursieve aanroepen te doen die kinderen van elke categorie ontdekken en de boomstructuur in de applicatie bouwen.

  2. Gebruik een van de algoritmen voor het opslaan van boomgegevens in een relationele database. Een van dergelijke algoritmen heet Modified Preorder Tree Traversal of gewoon MPTT.

Ervan uitgaande dat we kolommen lft . gebruiken en rgt om links / rechts indexen in traversal te behouden, wanneer u een nieuwe categorie invoegt, moet u:

  1. Informatie over bovenliggende categorieën ophalen op id:SELECT lft,rgt FROM tbl_categories WHERE categoryId=5 Laten we bijvoorbeeld aannemen dat de bovenliggende categorie lft=7 . had en rgt=10 (in dit geval heeft het al één kind)

  2. Maak ruimte voor een nieuwe invoer - verschuif alle records met 2 (1 voor lft en 1 voor 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

Noteer hier ORDER aflopend. Als lft en rgt worden verondersteld uniek te zijn, wordt geadviseerd om een ​​UNIQUE . te maken beperking op, en dan is een aflopende volgorde in de update nodig om dubbele sleutelfouten te voorkomen.

  1. Stel lft=<former parent rgt> . in en rgt=<former parent rgt +1> en voeg een nieuw record in...

    INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...

U kunt meer gedetailleerde voorbeelden met code vinden als u zoekt op MPTT PHP MySQL . Er zijn nogal wat tutorials over dit onderwerp.



  1. Hoe sluit je weekenden uit van een date_sub?

  2. Hoe maak je een SQL-weergave met SQLAlchemy?

  3. Doctrine 2 voegt een nieuw veld toe dat automatisch reekswaarden genereert

  4. Aan de slag met Amazon ECS en Amazon Fargate