Não há consulta SQL única que pode trazer resultados ordenados da maneira que você espera com base nessa estrutura de tabela.
Existem duas formas de resolver o problema:
-
Use a lógica do aplicativo externo (fora do banco de dados) para fazer chamadas recursivas que descobrirão os filhos de cada categoria e construirão a árvore no aplicativo.
-
Use um dos algoritmos para armazenar dados de árvore em um banco de dados relacional. Um desses algoritmos é chamadoModified Preorder Tree Traversal
ou simplesmente MPTT.
Assumindo que usamos colunas
lft
e rgt
para manter os índices esquerdo/direito na travessia, ao inserir uma nova categoria será necessário:-
Obter informações da categoria pai por ID:SELECT lft,rgt FROM tbl_categories WHERE categoryId=5
Vamos supor, por exemplo, que a categoria pai tenhalft=7
ergt=10
(neste caso já tem um filho)
-
Abra espaço para uma nova entrada - mude todos os registros em 2 (1 para lft e 1 para 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
Observe aqui
ORDER
descendente. Como lft
e rgt
devem ser únicos, é aconselhável fazer um UNIQUE
restrição sobre eles e, em seguida, a ordem decrescente na atualização é necessária para evitar erros de chave duplicada. -
Definirlft=<former parent rgt>
ergt=<former parent rgt +1>
e inserir um novo registro...
INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Você pode encontrar exemplos mais detalhados com código se pesquisar por
MPTT PHP MySQL
. Existem vários tutoriais sobre o assunto.