Mysql
 sql >> Base de données >  >> RDS >> Mysql

Sélection basée sur le chemin dans mysql

Juste pour vous donner un avertissement, ces solutions sont basées sur des comparaisons de chaînes, ne sont pas optimisées et ne peuvent pas utiliser d'index. vous devriez envisager de normaliser vos tables différemment. (Voir Gestion des données hiérarchiques dans MySQL )

Concernant certaines des questions :

Sélectionnez tous les enfants de l'identifiant 9 :

Depuis le Path colonne n'inclut pas les barres obliques de début et de fin, vous devez les concaténer au chemin :

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

sélectionnez un nombre total d'enfants de 9, x niveaux :

Nous devons regrouper par le nombre de barres obliques dans le chemin, moins le nombre de barres obliques dans le chemin parent :

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

Pour plus de simplicité, j'ai utilisé la requête ci-dessus pour afficher tous les niveaux. Si vous souhaitez limiter x niveaux en profondeur, utilisez le WHERE prédicat de la requête ci-dessous.

sélectionnez l'identifiant des enfants de 9 jusqu'à x niveaux, avec le niveau relatif à 9 :

Nous recherchons le Path colonne jusqu'à un nombre x de niveaux, en tenant compte du niveau des parents :

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

Les mesures que nous prenons :

  1. Nous devons découvrir la profondeur du parent, nous pouvons le trouver en comptant les barres obliques dans le chemin du parent. (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', '')) )
  2. Nous devons ajouter 1 à ce nombre, car un chemin avec 1 barre oblique a une profondeur de 2 niveaux.
  3. Nous ajoutons le nombre x de niveaux souhaités.
  4. Prenez la colonne du chemin jusqu'au niveau total, (utilisez les SUBSTRING_INDEX fonction).
  5. Ajoutez les barres obliques de début et de fin.
  6. Recherchez la chaîne finale pour 9.