Non esiste una singola query SQL che possono portarti risultati ordinati nel modo previsto in base a questa struttura della tabella.
Esistono due modi per risolvere il problema:
-
Usa la logica dell'applicazione esterna (al di fuori del DB) per effettuare chiamate ricorsive che rileveranno i bambini di ogni categoria e costruiranno l'albero nell'applicazione.
-
Utilizzare uno degli algoritmi per memorizzare i dati dell'albero in un database relazionale.Uno di questi algoritmi è chiamato
Modified Preorder Tree Traversal
o semplicemente MPTT.
Supponendo di utilizzare le colonne lft
e rgt
per mantenere gli indici sinistro/destro in attraversamento, quando inserirai una nuova categoria dovrai:
-
Ottieni informazioni sulla categoria principale in base all'ID:
SELECT lft,rgt FROM tbl_categories WHERE categoryId=5
Assumiamo, a titolo di esempio, che la categoria padre avesselft=7
ergt=10
(in questo caso ha già un figlio) -
Fai spazio a una nuova voce - sposta tutti i record di 2 (1 per lft e 1 per 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
Nota qui ORDER
discendente. Come lft
e rgt
dovrebbero essere univoci, si consiglia di creare un UNIQUE
vincolo su di essi, quindi è necessario un ordine decrescente nell'aggiornamento per evitare errori di chiave duplicati.
-
Imposta
lft=<former parent rgt>
ergt=<former parent rgt +1>
e inserisci un nuovo record...INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Puoi trovare esempi più dettagliati con il codice se cerchi MPTT PHP MySQL
. Ci sono parecchi tutorial su questo argomento.