usando recursivas jerárquicas jerarquica consultas consulta sql sql-server hierarchy hierarchical-data

recursivas - consulta jerarquica mysql



Contando el número de hijos en datos SQL jerárquicos (2)

Considere el uso de una forma transversal de árbol de preorden modificada para almacenar los datos jerárquicos. Consulte http://www.sitepoint.com/hierarchical-data-database/

Determinar el número de hijos para cualquier nodo se convierte en un simple:

SELECT (right-left-1) / 2 AS num_children FROM ...

para una estructura de datos simple tal como:

ID parentID Text Price 1 Root 2 1 Flowers 3 1 Electro 4 2 Rose 10 5 2 Violet 5 6 4 Red Rose 12 7 3 Television 100 8 3 Radio 70 9 8 Webradio 90

Para referencia, el árbol de jerarquía se ve así:

ID Text Price 1 Root |2 Flowers |-4 Rose 10 | |-6 Red Rose 12 |-5 Violet 5 |3 Electro |-7 Television 100 |-8 Radio 70 |-9 Webradio 90

Me gustaría contar el número de niños por nivel. Así que obtendría una nueva columna "NoOfChildren" así:

ID parentID Text Price NoOfChildren 1 Root 8 2 1 Flowers 3 3 1 Electro 3 4 2 Rose 10 1 5 2 Violet 5 0 6 4 Red Rose 12 0 7 3 Television 100 0 8 3 Radio 70 1 9 8 Webradio 90 0

Leí algunas cosas acerca de los datos jerárquicos, pero de alguna manera me quedo atascado en las múltiples uniones internas en los ID de padres. Quizás alguien pueda ayudarme aquí.


Usando un CTE obtendrías lo que quieres.

  • Recursivamente recorren todos los niños, recordando la raíz.
  • COUNT los elementos para cada raíz.
  • JOIN estos nuevamente con su tabla original para producir los resultados.

Datos de prueba

DECLARE @Data TABLE ( ID INTEGER PRIMARY KEY , ParentID INTEGER , Text VARCHAR(32) , Price INTEGER ) INSERT INTO @Data SELECT 1, Null, ''Root'', NULL UNION ALL SELECT 2, 1, ''Flowers'', NULL UNION ALL SELECT 3, 1, ''Electro'', NULL UNION ALL SELECT 4, 2, ''Rose'', 10 UNION ALL SELECT 5, 2, ''Violet'', 5 UNION ALL SELECT 6, 4, ''Red Rose'', 12 UNION ALL SELECT 7, 3, ''Television'', 100 UNION ALL SELECT 8, 3, ''Radio'', 70 UNION ALL SELECT 9, 8, ''Webradio'', 90

Declaración SQL

;WITH ChildrenCTE AS ( SELECT RootID = ID, ID FROM @Data UNION ALL SELECT cte.RootID, d.ID FROM ChildrenCTE cte INNER JOIN @Data d ON d.ParentID = cte.ID ) SELECT d.ID, d.ParentID, d.Text, d.Price, cnt.Children FROM @Data d INNER JOIN ( SELECT ID = RootID, Children = COUNT(*) - 1 FROM ChildrenCTE GROUP BY RootID ) cnt ON cnt.ID = d.ID