php – 根据mysql中的路径选择
我有一个列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但不包括子女 选择9个孩子的总计数,x级别深. 所以我想最终得到一行level1,level2,level3,… levelx或x行,代表不同的级别, 让我们假设这个例子的x是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,''),'/','')) 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,’/’,”))) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |