sql >> Base de Datos >  >> RDS >> Mysql

Consultar un recuento de elementos de un árbol

Dadas esas limitaciones, no hay manera. En tal caso, recuperaría todos el árbol y construir un lado del cliente 'colina', o realizar consultas recursivas, lo que sea más eficaz en el caso específico.

Con la restricción adicional de tener un número fijo de niveles de jerarquía , puedes hacer esto con un JOIN múltiple.

En el caso general, hay varias modificaciones de estructura para permitir superar esas restricciones. En la práctica, relaja la restricción "ESTA es la estructura de mi tabla", lo que permite agregar campos adicionales.

Por ejemplo, podría complementar la estructura del nodo con un left_id y asegúrese de que todos los ID de nodo estén en secuencia cuando visite el árbol primero en profundidad:

1 --- 2 -+- 3 -+- 4
         |     |
         |     +- 5
         +- 6 --- 7

En este caso, el nodo 3 almacenaría el valor "5", el nodo 6 almacenaría el valor "7" y el nodo 2 almacenaría el valor "7" también. Cada nodo almacena en LeftID el máximo entre los LeftID de sus hijos y su propio ID .

Entonces, los nodos sin hijos tienen LeftID igual a sus ID. El nodo 1 tendrá LeftID 7 ya que ese es el LeftID de 2, que lo obtuvo de 6.

En esta situación, contar nodos es fácil si no hay huecos en la secuencia; todos los descendientes de un nodo son aquellos nodos cuya ID está entre la ID del nodo inicial y su LeftID; y las hojas se identifican teniendo LeftID igual a ID.

Entonces, "todas las hojas que descienden del ID de nodo 17" serían

SELECT child.*FROM table AS parentJOIN table AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Descendant /WHERE child.id =child.leftid Hoja /AND parent.id =17; //em> El padre tiene 17 años

Esta estructura es complicada de mantener si desea poder podar y ramificar, ya que necesita volver a numerar todos los nodos entre el punto de podar hasta el punto de ramificación, así como los nodos movidos.

Otra posibilidad si solo te interesa contar es mantener un contador infantil. Esto se puede mantener actualizándolo iterativamente, seleccionando todas las hojas y configurando su contador en 0 (identifica las hojas a través de LEFT JOIN); luego todos esos padres con contadores NULL que tienen hijos con contadores no NULL, actualizando sus contadores a SUM() de contadores de niños más el COUNT() de los propios niños; y continuando hasta que el número de filas actualizadas sea cero, ya que todos los nodos tienen contadores no NULL. Después de podar y ramificar, simplemente establece todos los contadores en NULL y repite.

Este último enfoque cuesta una unión reflexiva para cada nivel de jerarquía.