Bonjour à vous experts PL/SQL!

À la suite d'une demande d'aide concernant une requête SQL récursive, on m'a conseillé d'utiliser le PL/SQL pour obtenir le résultat désiré. Malheureusement, je ne m'y connais pas en PL/SQL, alors j'apprécierais qu'on puisse m'aider à y arriver (idéalement avec une solution complète (fonctionnelle), détaillée et commentée).

La problématique est la suivante: J'essaie d'obtenir une liste de données classée par connectivité (relation parent-enfant), et ce, tout en omettant certains types de données dans un environnement Oracle 11gR2. Pour illustrer mes propos, c'est comme si je voulais partir d'un arbre généalogique et en créer un nouveau, mais en excluant les personnes ayant des cheveux roux (je n'ai rien contre les personnes rousses )...

À titre d'exemple, voici les informations que j'ai dans ma table que j'appelle "OriginalSequence"

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
WITH OriginalSequence AS
(
SELECT 'ID1' AS KEY, 'INVALID1' AS CHILD, NULL AS PARENT FROM dual union ALL
SELECT 'INVALID1'  , 'ID2'              , 'ID1'          FROM dual union ALL
SELECT 'INVALID1'  , 'ID3'              , 'ID1'          FROM dual union ALL
SELECT 'ID2'       , 'INVALID2'         , 'INVALID1'     FROM dual union ALL
SELECT 'ID3'       , 'ID4'              , 'INVALID1'     FROM dual union ALL
SELECT 'ID3'       , 'INVALID3'         , 'INVALID1'     FROM dual union ALL
SELECT 'INVALID2'  , NULL               , 'ID2'          FROM dual union ALL
SELECT 'ID4'       , NULL               , 'ID3'          FROM dual union ALL
SELECT 'INVALID3'  , 'ID5'              , 'ID3'          FROM dual union ALL
SELECT 'INVALID3'  , 'INVALID4'         , 'ID3'          FROM dual union ALL
SELECT 'ID5'       , 'ID6'              , 'INVALID3'     FROM dual union ALL
SELECT 'INVALID4'  , 'ID7'              , 'INVALID3'     FROM dual union ALL
SELECT 'ID6'       , NULL               , 'ID5'          FROM dual union ALL
SELECT 'ID7'       , 'ID8'              , 'INVALID4'     FROM dual union ALL
SELECT 'ID8'       , NULL               , 'ID7'          FROM dual
)
IMPORTANT: Même si dans mon exemple je montre le contraire, les données de ma "vraie" table NE SONT PAS triées en ordre de connectivité.


Dans ma table "OriginalSequence"
  • La colonne "KEY" est le nom de ma clé courante.
  • La colonne "Child" est le nom de la clé suivant (après) la clé courante.
  • La colonne "Parent" est le nom de la clé précédant (avant) la clé courante.
  • Est considéré "invalide" une clé qui débute par "INVALID".


De façon visuelle, les données de mon exemple ressemblent à ceci: http://i.xomf.com/npckv.png

Par contre, NE JAMAIS oublier que les données de ma "vrai" table NE SONT PAS triées en ordre de connectivité.

Alors, ce que j'aimerais faire c'est d'omettre (sauter par dessus) les données invalides de façon à avoir le résultat suivant:

KEY,NEW_CHILD,NEW_PARENT
ID1,ID2      ,null
ID1,ID3      ,null
ID2,null     ,ID1
ID3,ID4      ,ID1
ID3,ID5      ,ID1
ID3,ID7      ,ID1
ID4,null     ,ID3
ID5,ID6      ,ID3
ID6,null     ,ID5
ID7,ID8      ,ID3
ID8,null     ,ID7
Ce qui donne de façon visuelle ceci: http://i.xomf.com/vqqcp.png

Merci beaucoup!