Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Selecionando com base no caminho no mysql


Apenas para lhe dar um aviso, essas soluções são baseadas em comparações de strings, não são otimizadas e não podem usar índices. você deve considerar normalizar suas tabelas de forma diferente. (Consulte Gerenciando dados hierárquicos no MySQL )

Sobre algumas questões:

Selecione todos os filhos do ID 9:

Como o Path coluna não inclui as barras iniciais e finais, você precisa concatená-las ao caminho:
SELECT * 
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';

selecione uma contagem agregada de filhos de 9, x níveis de profundidade:

Precisamos agrupar pelo número de barras no caminho, menos o número de barras no caminho pai:
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

Para simplificar, usei a consulta acima para mostrar todos os níveis, se você deseja limitar x níveis de profundidade, use o WHERE predicado da consulta abaixo.

selecione os IDs dos filhos de 9 até x níveis, com o nível relativo a 9:

Pesquisamos o Path coluna até um número x de níveis, levando em consideração o nível dos pais:
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/%'

Os passos que estamos tomando:
  1. Precisamos descobrir a profundidade do pai, podemos descobrir isso contando as barras no caminho do pai. (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', '')) )
  2. Precisamos adicionar 1 a esse número, pois um caminho com 1 barra tem 2 níveis de profundidade.
  3. Adicionamos o número x de níveis desejados.
  4. Pegue a coluna de caminho até o nível total (use o SUBSTRING_INDEX função).
  5. Adicione a barra inicial e final.
  6. Pesquise a string final por 9.