Comptage du nombre d'enfants dans datatables SQL hiérarchiques

pour une structure de données simple telle que:

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 

Pour reference, l'arborescence de la hiérarchie ressemble à ceci:

 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 

Je voudrais countr le nombre d'enfants par niveau. Donc, je voudrais get une nouvelle colonne "NoOfChildren" comme ça:

 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 

J'ai lu quelques petites choses sur datatables hiérarchiques, mais je suis en quelque sorte coincé sur les multiples jointures internes sur les parentIDs. Peut-être que quelqu'un pourrait m'aider ici.

En utilisant un CTE , vous obtiendrez ce que vous voulez.

  • Récursivement parcourir tous les enfants, en se souvenant de la racine.
  • COUNT les éléments pour chaque racine.
  • JOIN les à nouveau avec votre table d'origine pour produire les résultats.

Données de test

 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 

Déclaration 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 

Envisagez d'utiliser une méthode de traversée d'tree de pré-command modifiée pour stocker datatables hiérarchiques. Voir http://www.sitepoint.com/hierarchical-data-database/

Déterminer le nombre d'enfants pour un nœud devient alors un simple:

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