在mysql中基于路径进行选择

| 我有一个列“ 0”,列“ 1”和列“ 2”,它们是物化路径。 看起来像
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的孩子
SELECT * FROM `tester` WHERE \'path\' LIKE \'%/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行中正常工作 所以
SELECT * FROM
tester
WHERE \'path\' LIKE \'1/%\' OR \'path\' LIKE \'%/1/%\'
; 我能提出最好的建议吗? 选择9个直属子级,但不选择子级子级 为此this11ѭtester
where \'parent\' = 9
;会很好的工作。 选择9个孩子的总数,x个深度。 因此,我想以with13ѭ的一行或代表不同级别的x行结束, 让我们假设本例中x为3 此示例中的行将为
9, 8, 6
(如果我们要求的话,第四层为3) 有任何想法吗? 编辑
#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;
**选择9的孩子ID到x级别,相对于9的级别 因此,对于本示例,我们将3用作x。 我们正在寻找回来
10 | 1
11 | 2
18 | 2
12 | 3
13 | 3
14 | 3 
我再次完全不知道该怎么做。 编辑:
#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;
    
已邀请:
        只是提醒您,这些解决方案基于字符串比较,没有经过优化并且不能使用索引。您应该考虑以其他方式标准化表格。 (请参阅在MySQL中管理分层数据) 关于一些问题: 选择所有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个: 我们在
Path
列中搜索多达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/%\'
我们正在采取的步骤: 我们需要找出父级有多深,我们可以通过计算父级路径中的斜线来发现。 (
LENGTH(p.Path) - LENGTH(REPLACE(p.Path, \'/\', \'\'))
) 我们需要在该数字上加1,因为斜线为1的路径深2级。 我们将所需数量的x数量相加。 抓取路径列直至总计(使用
SUBSTRING_INDEX
功能)。 添加前导和尾部斜杠。 在最后的字符串中搜索9。     

要回复问题请先登录注册