Based on this question, have any way to implement a parent level count?
Find highest level of a hierarchical field: with vs without CTEs
Example table:
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 0 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 3 |
| 8 | 5 |
| 9 | 5 |
| 10 | 7 |
+----+-----------+
Function:
DELIMITER $$
DROP FUNCTION IF EXISTS `junk`.`GetFamilyTree` $$
CREATE FUNCTION `junk`.`GetFamilyTree` (GivenID INT, Count INT) RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE rv,q,queue,queue_children VARCHAR(1024);
DECLARE queue_length,front_id,pos INT;
SET rv = '';
SET queue = GivenID;
SET queue_length = 1;
SET count_limit = Count;
WHILE queue_length > 0 && count_limit > 0 DO
SET front_id = FORMAT(queue,0);
IF queue_length = 1 THEN
SET queue = '';
ELSE
SET pos = LOCATE(',',queue) + 1;
SET q = SUBSTR(queue,pos);
SET queue = q;
END IF;
SET queue_length = queue_length - 1;
SELECT IFNULL(qc,'') INTO queue_children
FROM (SELECT GROUP_CONCAT(id) qc
FROM pctable WHERE parent_id = front_id) A;
IF LENGTH(queue_children) = 0 THEN
IF LENGTH(queue) = 0 THEN
SET queue_length = 0;
END IF;
ELSE
IF LENGTH(rv) = 0 THEN
SET rv = queue_children;
ELSE
SET rv = CONCAT(rv,',',queue_children);
END IF;
IF LENGTH(queue) = 0 THEN
SET queue = queue_children;
ELSE
SET queue = CONCAT(queue,',',queue_children);
END IF;
SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1;
END IF;
END WHILE;
RETURN rv;
END $$
I need implement a count on that function to limit iterate based on parameter passed on query.
SELECT id,parent_id, GetFamilyTree(1, 3) FROM pctable;
Detail: first param is id of desired family tree
secund param is a level depth of descendants
Example result of example table:
+----+-----------+
| id | parent_id |
+----+-----------+
| 1| 0 |
| 2| 1 |
| 3| 1 |
| 4| 2 |
| 5| 2 |
| 6| 3 |
| 7| 3 |
+----+-----------+
It is possible?
In this case, the count not working as well…its counting every tree item, not every tree level.
Best Answer
If you look at the
GetFamilyTree
code, there is nothing monitoring the tree height or any particular level.To compensate, I have a revised version of this code
This is how I changed it: For each id in the queue, I introduce a height.
Each member of the list will look like this:
I place a limit on when to concatenate by adding
IF front_ht < LevelLimit THEN
When the list is compiled, I then taken the return value
rv
and remove all colons (:
) and the number behind each colon. What's left is a comma-separated list of IDs within the height range set byLevelLimit
. If you want the height to be included in the output, remove theStrip away level parts of the output
code at the bottom of the Stored Procedure.Give it a Try !!!
UPDATE 2014-11-29 16:05 EST
It is important to note that you need to make GROUP_CONCAT have enough space to collect a long list of info. Please run this in mysql:
Then, add this to
my.cnf