Selecting based on path in mysql

£可爱£侵袭症+ 提交于 2019-12-04 09:35:16

Just to give you a heads up, these solutions are based on string comparisons, are not optimized & cannot use indexes. you should consider normalizing your tables differently. (See Managing Hierarchical Data in MySQL)

Regarding some of the questions:


Select all children of id 9:

Since the Path column does not include the leading & trailing slashes, you need to concatenate them to the path:

SELECT * 
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';

select an aggregate count of 9's children, x levels deep:

We need to group by the number of slashes in the path, minus the number of slashes in the parent path:

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

For simplicity i used the query above to show all the levels, If you want to limit x levels deep, use the WHERE predicate from the query below.


select 9's children's id's down to x levels, with the level relative to 9:

We search the Path column up to a x number of levels, while taking the parents level into consideration:

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/%'

The steps we are taking:

  1. We need to find out how deep the parent is, we can find that by counting the slashes in the parent's path. (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', '')))
  2. We need to add 1 to that number, since a path with 1 slash is 2 levels deep.
  3. We add the x number of desired levels.
  4. Grab the path column up to the level total, (Use the SUBSTRING_INDEX function).
  5. Add the leading and trailing slash.
  6. Search the final string for 9.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!