Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting number of children in hierarchical SQL data

for a simple data structure such as so:

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

For reference, the hierarchy tree looks like this:

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

I'd like to count the number of children per level. So I would get a new column "NoOfChildren" like so:

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

I read a few things about hierarchical data, but I somehow get stuck on the multiple inner joins on the parentIDs. Maybe someone could help me out here.

like image 596
Dennis G Avatar asked Feb 26 '10 09:02

Dennis G


People also ask

How do I count the number of employees in SQL?

SELECT department, COUNT(*) AS "Number of employees" FROM employees WHERE state = 'CA' GROUP BY department; Because you have listed one column in your SELECT statement that is not encapsulated in the COUNT function, you must use a GROUP BY clause.

How do I count counts in SQL query?

SELECT COUNT(*) FROM table_name; The COUNT(*) function will return the total number of items in that group including NULL values. The FROM clause in SQL specifies which table we want to list. You can also use the ALL keyword in the COUNT function.

How fetch data is hierarchical in SQL?

Use hierarchyid as a data type to create tables with a hierarchical structure, or to describe the hierarchical structure of data that is stored in another location. Use the hierarchyid functions in Transact-SQL to query and manage hierarchical data.

Can you GROUP BY count in SQL?

SQL – count() with Group By clause The count() function is an aggregate function use to find the count of the rows that satisfy the fixed conditions. The count() function with the GROUP BY clause is used to count the data which were grouped on a particular attribute of the table.


2 Answers

Using a CTE would get you what you want.

  • Recursively go through all children, remembering the root.
  • COUNT the items for each root.
  • JOIN these again with your original table to produce the results.

Test Data

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

SQL Statement

;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
like image 136
Lieven Keersmaekers Avatar answered Sep 26 '22 17:09

Lieven Keersmaekers


Consider using a modified preorder tree traversal way of storing the hierarchical data. See http://www.sitepoint.com/hierarchical-data-database/

Determining number of children for any node then becomes a simple:

SELECT (right-left-1) / 2 AS num_children FROM ...
like image 30
mxsscott Avatar answered Sep 29 '22 17:09

mxsscott