Vous pouvez utiliser un recursive CTE pour cela:
WITH RECURSIVE recCTE AS
(
/*Get all the true children to seed the recursive query*/
SELECT
id,
parent_id,
condition as initial_condition,
1 as depth,
CAST(id as varchar(50)) as path
FROM
table a
WHERE
a.id NOT IN (SELECT DISTINCT parent_id from table)
and a.condition = 'true'
UNION ALL
/*Recursive bit that refers back to itself. Find the parents*/
SELECT
b.id,
b.parent_id,
a.initial_condition,
depth + 1 as depth,
cast(path || '>' || b.id as varchar(50)) as path
FROM
recCTE a
INNER JOIN table b ON
a.parent_id = b.id
WHERE
/*avoid going too deep in case of cycling*/
depth <= 20
)
SELECT * FROM recCTE
Le CTE récursive utilise deux parties:
La graine récursive: Ceci est la première moitié de la requête UNION. Dans ce, nous identifions tous les enfants (ID qui ne sont pas aussi Parent_IDs) qui sont "True"
Le terme récursif: C'est la deuxième moitié de la requête UNION. Il se réfère à lui-même (recCTE) dans la clause FROM et joint table
à nouveau; reliant le recCTE.parent_id (itérations précédentes parent_id) à id
de la table. Puis tire toutes les informations nécessaires pour cette itération.
Je presque toujours suivies de la profondeur récursive (combien de récurrences at-il fallu pour arriver à ce dossier), et le chemin (à partir du fond plus enfant que d'autres nœuds de cette hiérarchie ne nous a frappé pour se rendre à cet enregistrement). J'utilise la profondeur pour m'assurer que nous n'allons pas trop loin dans le trou du lapin. Dans le cas où vous avez des documents tels que:
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 5 |
| 5 | 7 |
| 7 | 1 |
+----+-----------+
qui provoqueraient une boucle infinie (cycliste) le scénario du pire est-il arrêtera après il va 20 cycles profonds (1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5). Il y a d'autres façons d'arrêter de faire du vélo, comme utiliser le champ de chemin: WHERE a.path NOT LIKE '%' || a.parent_id || '%'
par exemple.
Vous pouvez obtenir un peu plus d'élégance avec cette sélection finale si vous en avez besoin, mais cela vous permettra d'atteindre 95% du chemin.
Wow man, explication vraiment sympa, je suis devenu fou avec ça, je lis un peu sur le CTE récursif et suis émerveillé! Entièrement sauvé la journée grâce à vous. J'ai adapté la requête à ma table et était bien: D –
Great! Je suis content que cela a marché pour vous dès la sortie de la boîte. Il y a certainement une courbe d'apprentissage pour les CTE récursifs, mais une fois que vous les avez compris, ils sont tout à fait compréhensibles et constituent un excellent outil pour la boîte à outils. – JNevill