加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – 根据mysql中的路径选择

发布时间:2020-12-13 22:30:53 所属栏目:PHP教程 来源:网络整理
导读:我有一个列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
我有一个列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/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 | 1920  
21 | 19 | 1921

我需要根据这个表做一些查询.

我需要做的查询是

选择所有id为9的孩子

SELECT * FROM `tester` WHERE 'path' LIKE '%/9/%';

工作正常,直到你用1或19替换ID,因为没有/在开头.

SELECT * FROM `tester` WHERE 'path' LIKE '%1/%';

将选择数字以1结尾的所有行,因此,1,11,21,31,211等

SELECT * FROM `tester` WHERE 'path' LIKE '1/%';

适用于第1行或第19行

所以SELECT * FROMtesterWHERE’路径’LIKE’1 /%’或’路径’LIKE’%/ 1 /%’;
我能想出最好的,有什么建议吗?

选择直接子女为9但不包括子女
对于这个Select * fromtesterwhere’parent’= 9;会很好的.

选择9个孩子的总计数,x级别深.

所以我想最终得到一行level1,level2,level3,… levelx或x行,代表不同的级别,

让我们假设这个例子的x是3
这个例子中的行将是9,8,6(如果我们要求它将是3级的第4级)

有任何想法吗?

编辑

#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,''),'/','')) 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.*,'%') 
WHERE parent.id  =9 
GROUP BY id HAVING LEVEL <= 3 AND LEVEL > 0;

解决方法

为了让您了解一下,这些解决方案基于字符串比较,未经过优化和优化.不能使用索引.您应该考虑以不同方式规范化表格. (见 Managing Hierarchical Data in 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('/','/') 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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读