Question SQL: Obtenir les lignes du parent suivies par les lignes enfants
-
05-07-2019 - |
Question
id parent_id
1 0
2 0
3 2
4 0
5 1
6 0
J'ai besoin d'une requête qui renverra des lignes parent (id_ parent = 0) suivies de ses lignes enfant
premier parent
tous les enfants du premier parent
deuxième parent
tous les enfants du deuxième parent
troisième parent
quatrième parent
Résultat attendu: classé par identifiant
id parent_id
1 0 (premier parent)
5 1 (tous les enfants du premier parent)
2 0 deuxième parent
3 2 (tous les enfants du deuxième parent)
4 0 troisième parent
6 0 quatrième parent
Je peux utiliser l'union des parents suivie de tous les enfants Mais cela me donne d'abord les parents, puis les enfants. J'ai besoin d'un parent et immédiatement de ses enfants.
Tout le monde peut aider?
La solution
Vous utiliseriez un CTE récursif pour cela:
WITH r AS
(SELECT id,
NULL AS parent_id,
CAST(right('000' + CAST(row_number()
OVER (table.id) AS varchar), 3) AS varchar(50))
FROM table WHERE parent IS NULL
UNION ALL
SELECT table.id, table.parent_id,
CAST(r.ord + right('000' + CAST(row_number()
OVER (ORDER BY table.id) AS varchar), 3) AS varchar(50))
FROM r JOIN table
ON table.parent = r.id)
SELECT id
FROM r
ORDER BY left(ord + '000000000000000000000000000000000', 36)
Notez que cette version s’arrêtera si un identifiant a une valeur supérieure à 999, et elle se cassera si vous avez plus de 12 niveaux. Si cela vous préoccupe, vous devez ajuster le nombre de zéros aux différents endroits.
Il y a peut-être de meilleurs moyens, mais celui-ci fonctionne.
Autres conseils
Voici un exemple de solution utilisant une union avec une clause order by (cela ne fonctionnera pas pour une imbrication profonde).
SELECT p.id,
p.parent_id,
p.name,
p.id AS sequence
FROM topics AS p
WHERE p.parent_id = 0
UNION
SELECT t.id,
t.parent_id,
t.name,
t.parent_id AS sequence
FROM topics AS t
WHERE t.parent_id <> 0
ORDER BY sequence, parent_id, name
Autant que je sache, vous ne pouvez pas le faire avec une seule instruction SQL si tout ce que vous stockez est l'identifiant du parent. Si vous devez extraire rapidement l’arborescence de données, vous devrez envisager de stocker un parcours de pré-commande. C’est plus simple que cela en a l’air et cela est très bien décrit ici: http: //articles.sitepoint. com / article / hierarchical-data-database