I'm trying to obtain all children count from each parent (where subchildren counts).
This is the sample database (MSSQL).
INSERT INTO NODES VALUES(NULL, 1);
INSERT INTO NODES VALUES(NULL, 2);
INSERT INTO NODES VALUES(2, 3);
INSERT INTO NODES VALUES(1, 4);
INSERT INTO NODES VALUES(1, 5);
INSERT INTO NODES VALUES(3, 6);
INSERT INTO NODES VALUES(NULL, 7);
INSERT INTO NODES VALUES(NULL, 8);
INSERT INTO NODES VALUES(8, 9);
INSERT INTO NODES VALUES(7, 10);
INSERT INTO NODES VALUES(9, 11);
INSERT INTO NODES VALUES(11, 12);
INSERT INTO NODES VALUES(10, 13);
INSERT INTO NODES VALUES(10, 14);
INSERT INTO NODES VALUES(4, 15);
Where the hierarchy is;
- 1
- 4
- 15
- 5
- 2
- 3
- 6
- 7
- 10
- 13
- 14
- 8
- 9
- 11
- 12
And the desired result is:
| id | Children Count |
|---|---|
| 1 | 3 |
| 4 | 1 |
| 5 | 0 |
| 2 | 2 |
| 3 | 1 |
| 6 | 0 |
| 7 | 3 |
| 10 | 2 |
| 13 | 1 |
| 14 | 0 |
| 8 | 3 |
| 9 | 2 |
| 11 | 1 |
| 12 | 0 |
Every time I make a strategy to formulate a query, I get to the point where I must iterate the table formed by the query at running time.
If I go deep out grouping the results (with the parentid) I could generate a count of only the children (not the subchildren), so that we can add up to the root. But clearly I would need to iterate the table that I have been forming in the query, I don't know if it would be correct to say recursively.
To express myself better I will show it with the part I have reached and what I want to do;
WITH tree AS
(
SELECT n1.parentid, n1.id, 1 AS level
FROM NODES AS n1
WHERE n1.parentid IS NULL
UNION ALL
SELECT n2.parentid, n2.id, level + 1 AS level
FROM NODES AS n2
INNER JOIN tree ON n2.parentid = tree.id
), levels AS
(
SELECT *
FROM tree
)
SELECT parentid, id, (COUNT(*) OVER(PARTITION BY parentid ORDER BY parentid)) AS childrencountofparentid,
ROW_NUMBER() OVER(ORDER BY parentid DESC) AS rownumber
FROM levels
Where the output is:
| parentid | id | childrencountofparentid | rownumber |
|---|---|---|---|
| 11 | 12 | 1 | 1 |
| 10 | 13 | 2 | 2 |
| 10 | 14 | 2 | 3 |
| 9 | 11 | 1 | 4 |
| 8 | 9 | 1 | 5 |
| 7 | 10 | 1 | 6 |
| 4 | 15 | 1 | 7 |
| 3 | 6 | 1 | 8 |
| 2 | 3 | 1 | 9 |
| 1 | 4 | 2 | 10 |
| 1 | 5 | 2 | 11 |
| null | 1 | 4 | 12 |
| null | 2 | 4 | 13 |
| null | 7 | 4 | 14 |
| null | 8 | 4 | 15 |
I want to do this:
Full Image
I want to use the results of the previous rows, similar to lag but i must iterate all previous rows.