Om u op de hoogte te houden, deze oplossingen zijn gebaseerd op stringvergelijkingen, zijn niet geoptimaliseerd en kunnen geen indexen gebruiken. je zou moeten overwegen om je tabellen anders te normaliseren. (Zie Hiërarchische gegevens beheren in MySQL )
Met betrekking tot enkele van de vragen:
Selecteer alle kinderen van id 9:
Sinds het Path
kolom bevat geen voorloop- en achterslashes, u moet ze samenvoegen met het pad:
SELECT *
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
selecteer een totaal aantal van 9 kinderen, x niveaus diep:
We moeten groeperen op het aantal schuine strepen in het pad, minus het aantal schuine strepen in het bovenliggende pad:
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
Voor de eenvoud heb ik de bovenstaande query gebruikt om alle niveaus te tonen. Als je x niveaus diep wilt beperken, gebruik dan de WHERE
predikaat uit de onderstaande zoekopdracht.
selecteer de kinder-ID's van 9 tot x niveaus, met het niveau ten opzichte van 9:
We zoeken het Path
kolom tot een x aantal niveaus, rekening houdend met het bovenliggende niveau:
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/%'
De stappen die we nemen:
- We moeten uitzoeken hoe diep de ouder is, dat kunnen we vinden door de schuine strepen in het pad van de ouder te tellen. (
LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))
) - We moeten 1 bij dat getal optellen, aangezien een pad met 1 schuine streep 2 niveaus diep is.
- We voegen het x aantal gewenste niveaus toe.
- Pak de padkolom naar het niveautotaal, (gebruik de
SUBSTRING_INDEX
functie). - Voeg de eerste en laatste slash toe.
- Zoek in de laatste tekenreeks naar 9.