Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consultando uma contagem de itens de uma árvore


Dadas essas restrições, não há como. Nesse caso, você recuperaria todos a árvore e construir um lado do cliente 'hill', ou executar consultas recursivas, o que for mais eficiente no caso específico.

Com a restrição adicional de ter um número fixo de níveis de hierarquia , você pode fazer isso com um JOIN múltiplo.

No caso geral, existem várias modificações na estrutura para permitir a superação dessas restrições. Na prática você relaxa a restrição "THIS is my table structure", permitindo a adição de campos adicionais.

Por exemplo, você pode complementar a estrutura do nó com um left_id valor e certifique-se de que todos os IDs de nó estejam em sequência quando você visitar a árvore em profundidade:
1 --- 2 -+- 3 -+- 4
         |     |
         |     +- 5
         +- 6 --- 7

Neste caso, o nó 3 armazenaria o valor "5", o nó 6 armazenaria o valor "7" e o nó 2 armazenaria o valor "7" também. Cada nó armazena em LeftID o máximo entre os LeftIDs de seus filhos e seu próprio ID .

Portanto, os nós sem filhos têm LeftID igual aos seus IDs. O nó 1 terá LeftID 7, pois esse é o LeftID de 2, que o obteve de 6.

Nesta situação, contando nós é fácil se não houver furos na sequência; todos os descendentes de um nó são aqueles nós cujo ID está entre o ID do nó inicial e seu LeftID; e folhas são identificadas por ter LeftID igual a ID.

Portanto, "todas as folhas descendentes do ID do nó 17" seriam

SELECT child.*FROM table AS parentJOIN table AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Descendente /WHERE child.id =child.leftid / Folha /AND parent.id =17; / Pai tem 17 anos

Essa estrutura é difícil de manter se você quiser fazer poda e ramificação, pois você precisa renumerar todos os nós entre o ponto de poda até o ponto de ramificação, bem como os nós movidos.

Outra possibilidade, se você estiver interessado apenas em contar, é manter um contador infantil. Isso pode ser mantido atualizando-o iterativamente, selecionando todas as folhas e definindo seu contador para 0 (você identifica as folhas por meio de um LEFT JOIN); então todos aqueles pais com contadores NULL que têm filhos com contadores não NULL, atualizando seus contadores para o SUM() de contadores de crianças mais o COUNT() das próprias crianças; e continuando até que o número de linhas atualizadas se torne zero, pois todos os nós têm contadores não NULL. Após uma poda e ramificação, basta definir todos os contadores para NULL e repetir.

Esta última abordagem custa uma junção reflexiva para cada nível de hierarquia.