Php mysql中基于路径的选择
我有一个列id、一个列父级和一个作为物化路径的列路径 看起来像Php mysql中基于路径的选择,php,mysql,sql,materialized-path-pattern,Php,Mysql,Sql,Materialized Path Pattern,我有一个列id、一个列父级和一个作为物化路径的列路径 看起来像 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/
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
我需要根据这个表进行一些查询
我需要做的查询是
选择id为9的所有子项
可以正常工作,直到您将ID替换为1或19,因为开始时没有/
SELECT * FROM `tester` WHERE 'path' LIKE '%1/%';
将选择数字以1结尾的所有行,因此,1、11、21、31、211等
SELECT * FROM `tester` WHERE 'path' LIKE '1/%';
将对第1行或第19行正常工作
因此,从tester中选择*path,如“1/%”或“%/1/%”等;
是我能想到的最好的,有什么建议吗
选择9的直接子级,但不选择子级
为此,选择*fromtesterwhere'parent'=9;会很好的
选择9的子级的聚合计数,x级深度
所以我想以一行level1,level2,level3。。。levelx或x行,表示不同的级别
在这个例子中,让我们假设x是3
这个例子中的行是9,8,6,如果我们要求它是3,那么它将是第4级
有什么想法吗
编辑
我再一次完全不知道该怎么做
编辑:
这些解决方案基于字符串比较,没有经过优化,不能使用索引。你应该考虑用不同的方式规范你的表格。看 关于一些问题: 选择id为9的所有子项: 由于Path列不包含前导斜杠和尾随斜杠,因此需要将它们连接到路径:
SELECT *
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
选择9的子级的合计计数,x级深度:
我们需要按路径中的斜线数减去父路径中的斜线数进行分组:
SELECT (LENGTH(c.Path) - LENGTH(REPLACE(c.Path, '/', '')))
- (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))) AS Level,
COUNT(*)
FROM tester c
JOIN tester p ON c.Parent = p.ID
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
GROUP BY 1
为了简单起见,我使用上面的查询来显示所有级别,如果您想限制x个级别的深度,请使用下面查询中的WHERE谓词
选择9的子id向下至x级别,级别相对于9:
我们将路径列搜索到x个级别,同时考虑父级:
SELECT c.*
FROM tester c
JOIN tester p ON c.Parent = p.ID
WHERE CONCAT(
'/',
SUBSTRING_INDEX(
Path,
'/',
(LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))) + 4
),
'/') LIKE '%/9/%'
我们正在采取的步骤:
我们需要找出父级的深度,我们可以通过计算父级路径中的斜线来找到。LENGTHp.Path-LENGTHREPLACEp.Path“/”,
我们需要在这个数字上加1,因为带1斜杠的路径有2层深。
我们添加x个所需级别。
抓取路径列,直到总计级别,使用函数。
添加前导斜杠和尾随斜杠。
在最后一个字符串中搜索9。
你能更详细地解释你所说的9个孩子的总数是什么意思吗,x级深度?嗨,Scrum大师,为这些欢呼,根据你的评论,我的意思是,在每一级我想知道有多少个孩子居住,在这种情况下,孙子不被视为孩子。
#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;
SELECT *
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
SELECT (LENGTH(c.Path) - LENGTH(REPLACE(c.Path, '/', '')))
- (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))) AS Level,
COUNT(*)
FROM tester c
JOIN tester p ON c.Parent = p.ID
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
GROUP BY 1
SELECT c.*
FROM tester c
JOIN tester p ON c.Parent = p.ID
WHERE CONCAT(
'/',
SUBSTRING_INDEX(
Path,
'/',
(LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))) + 4
),
'/') LIKE '%/9/%'