Est-ce que postgresql prend en charge les requêtes récursives qui utilisent les clauses WITH? Si c'est le cas, quelque chose comme ça pourrait fonctionner. (Si vous voulez une réponse testée, fournir des instructions CREATE TABLE et INSERT dans votre question, ainsi que les résultats dont vous avez besoin pour les données d'échantillon dans les INSERTs.)
with Links(id,link,data) as (
select
id, redirectid, data
from T
where redirectid is null
union all
select
id, redirectid, null
from T
where redirectid is not null
union all
select
Links.id,
T.redirectid,
case when T.redirectid is null then T.data else null end
from T
join Links
on Links.link = T.id
)
select id, data
from Links
where data is not null;
Remarques complémentaires:
:(Vous pouvez implémenter la récursion vous-même en fonction de l'expression WITH Je ne connais pas la syntaxe postgresql pour la programmation séquentielle, donc c'est un peu pseudo:
Insérez le résultat de cette requête dans une nouvelle table appelée Liens:
select
id, redirectid as link, data, 0 as depth
from T
where redirectid is null
union all
select
id, redirectid, null, 0
from T
where redirectid is not null
Déclare également un entier :: depth et l'initialise à zéro. Puis répétez les opérations suivantes jusqu'à ce qu'il n'ajoute plus de lignes aux liens. Les liens contiendront alors votre résultat.
increment ::depth;
insert into Links
select
Links.id,
T.redirectid,
case when T.redirectid is null then T.data else null end,
depth + 1
from T join Links
on Links.link = T.id
where depth = ::depth-1;
end;
Je pense que ce sera mieux que n'importe quelle solution de curseur. En fait, je ne peux pas vraiment penser à la façon dont les curseurs seraient utiles pour ce problème. Notez que cela ne se terminera pas s'il y a des cycles (redirections qui sont finalement circulaires).
Malheureusement il semble que le support récursif n'a pas été ajouté jusqu'à 8.4 –
Voir mes remarques supplémentaires dans la réponse. –