I have a column id
, a column parent
and a column path
that is a materialized path.
It looks like
1 | \N | 1
2 | 1 | 1/2
3 | 2 | 1/2/3
4 | 3 | 1/2/3/4
5 | 3 | 1/2/3/5
6 | 2 | 1/2/6
7 | 6 | 1/2/6/7
8 | 2 | 1/2/8
9 | 1 | 1/9
10 | 9 | 1/9/10
11 | 10 | 1/9/10/11
12 | 11 | 1/9/10/11/12
13 | 11 | 1/9/10/11/13
14 | 11 | 1/9/10/11/14
15 | 14 | 1/9/10/11/14/15
16 | 14 | 1/9/10/11/14/16
17 | 14 | 1/9/10/11/14/17
18 | 10 | 1/9/10/18
19 | \N | 19
20 | 19 | 19\20
21 | 19 | 19\21
I need to do some queries based off this table.
The queries I need to do are
Select all children of
id
9
SELECT * FROM `tester` WHERE 'path' LIKE '%/9/%';
Would work fine, Until you replace the ID with 1 or 19 as there is no /
at the beginning.
SELECT * FROM `tester` WHERE 'path' LIKE '%1/%';
would select all rows where a number ends in 1, so, 1, 11, 21, 31, 211 etc
SELECT * FROM `tester` WHERE 'path' LIKE '1/%';
would work correctly for either rows 1 or 19
So SELECT * FROM
testerWHERE 'path' LIKE '1/%' OR 'path' LIKE '%/1/%'
;
Is the best I can come up with, any suggestions?
Select Direct children of 9 but not sub-children
For this
Select * from
testerwhere 'parent' = 9
; will work fine.
select an aggregate count of 9's children, x levels deep.
So I want to end up with either one row of level1, level2, level3, ... levelx
or x rows, representing the different levels,
Let us pretend x is 3 for this example
The rows from this example would be 9, 8, 6
(the 4th level if we requested it would be 3)
Any Ideas?
Edit
#select count of children of specific node(5) down to a maximum of three levels, do no include the parent
SELECT COUNT(child.id) children,
LENGTH(REPLACE(child.path, parent.path, '')) - LENGTH(REPLACE(REPLACE(child.path, parent.path, ''), '/', '')) AS LEVEL
FROM `tester` child JOIN `tester` parent ON child.path LIKE CONCAT(parent.path,'%')
WHERE parent.id =5
GROUP BY LEVEL HAVING LEVEL <= 3 AND LEVEL > 0;
**select 9's children's id's down to x levels, with the level relative to 9,
So again for this example we will use 3 as x.
We are looking to get back
10 | 1
11 | 2
18 | 2
12 | 3
13 | 3
14 | 3
Again I am at a complete loss as to how to do this.
Edit:
#select all information, and relative level from parent of children of specific node(5) down to a maximum of three levels, do no include the parent
SELECT child.*,
LENGTH(REPLACE(child.path, parent.path, '')) - LENGTH(REPLACE(REPLACE(child.path, parent.path, ''), '/', '')) AS LEVEL
FROM `tester` child JOIN `tester` parent ON child.path LIKE CONCAT(parent.path,'%')
WHERE parent.id =9
GROUP BY id HAVING LEVEL <= 3 AND LEVEL > 0;