Mysql
 sql >> Database >  >> RDS >> Mysql

Selezione in base al percorso in mysql

Solo per avvisarti, queste soluzioni si basano su confronti di stringhe, non sono ottimizzate e non possono utilizzare indici. dovresti considerare di normalizzare le tue tabelle in modo diverso. (Vedi Gestione dei dati gerarchici in MySQL )

Per quanto riguarda alcune delle domande:

Seleziona tutti i bambini con ID 9:

Dal Path colonna non include le barre iniziali e finali, devi concatenarle al percorso:

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

seleziona un conteggio aggregato di figli di 9, x livelli di profondità:

Dobbiamo raggruppare in base al numero di barre nel percorso, meno il numero di barre nel percorso principale:

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

Per semplicità ho usato la query sopra per mostrare tutti i livelli, se vuoi limitare x livelli in profondità, usa il WHERE predicato dalla query seguente.

seleziona l'ID dei bambini di 9 fino a x livelli, con il livello relativo a 9:

Cerchiamo il Path colonna fino a un numero x di livelli, tenendo in considerazione il livello genitori:

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

I passi che stiamo facendo:

  1. Dobbiamo scoprire quanto è profondo il genitore, possiamo scoprirlo contando le barre nel percorso del genitore. (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', '')) )
  2. Dobbiamo aggiungere 1 a quel numero, poiché un percorso con 1 barra è profondo 2 livelli.
  3. Aggiungiamo il numero x di livelli desiderati.
  4. Afferra la colonna del percorso fino al totale del livello (utilizza le SUBSTRING_INDEX funzione).
  5. Aggiungi la barra iniziale e finale.
  6. Cerca 9 nella stringa finale.