récursive - sql with




Requête récursive SQL sur la table auto-référencée(Oracle) (4)

C'est un peu lourd, mais je pense que cela devrait fonctionner (sans le joint supplémentaire). Cela suppose que vous pouvez choisir un personnage qui n'apparaîtra jamais dans le champ en question, pour agir comme séparateur.

Vous pouvez le faire sans imbriquer le select, mais je trouve cela un peu plus propre avec quatre références à SYS_CONNECT_BY_PATH.

select id, 
       parent_id, 
       case 
         when lvl <> 1 
         then substr(name_path,
                     instr(name_path,'|',1,lvl-1)+1,
                     instr(name_path,'|',1,lvl)
                      -instr(name_path,'|',1,lvl-1)-1) 
         end as name 
from (
  SELECT id, parent_id, sys_connect_by_path(name,'|') as name_path, level as lvl
  FROM tbl 
  START WITH id = 1 
  CONNECT BY PRIOR id = parent_id)

Supposons que j'ai ces exemples de données:

| Name     | ID | PARENT_ID |
-----------------------------
| a1       | 1  | null      |
| b2       | 2  | null      |
| c3       | 3  | null      |
| a1.d4    | 4  | 1         |
| a1.e5    | 5  | 1         |
| a1.d4.f6 | 6  | 4         |
| a1.d4.g7 | 7  | 4         |
| a1.e5.h8 | 8  | 5         |
| a2.i9    | 9  | 2         |
| a2.i9.j10| 10 | 9         |

Je voudrais sélectionner tous les enregistrements à partir de accountId = 1, le résultat attendu serait donc:

| Name     | ID | PARENT_NAME | PARENT_ID | 
-------------------------------------------
| a1       | 1  | null        | null      |
| a1.d4    | 4  | a1          | 1         |
| a1.e5    | 5  | a1          | 1         |
| a1.d4.f6 | 6  | a1.d4       | 4         |
| a1.d4.g7 | 7  | a1.d4       | 4         |
| a1.e5.h8 | 8  | a1.e5       | 5         |

Je suis actuellement en mesure de faire la sélection récursive, mais alors je ne peux pas accéder aux données de la référence parente, donc je ne peux pas renvoyer parent_name. Le code que j'utilise est (adapté à l'exemple simpliste):

SELECT id, parent_id, name
FROM tbl 
  START WITH id = 1 
  CONNECT BY PRIOR id = parent_id

Quel SQL dois-je utiliser pour la récupération mentionnée ci-dessus?

Mots-clés supplémentaires pour les futurs demandeurs: SQL pour sélectionner les données hiérarchiques représentées par les clés parent dans la même table


Qu'en est-il de l'utilisation de PRIOR,

alors

SELECT id, parent_id, PRIOR name
   FROM tbl 
START WITH id = 1 
CONNECT BY PRIOR id = parent_id`

ou si vous voulez obtenir le nom de la racine

SELECT id, parent_id, CONNECT_BY_ROOT name
   FROM tbl 
START WITH id = 1 
CONNECT BY PRIOR id = parent_id


Utilisation:

    SELECT t1.id, 
           t1.parent_id, 
           t1.name,
           t2.name AS parent_name,
           t2.id AS parent_id
      FROM tbl t1
 LEFT JOIN tbl t2 ON t2.id = t1.parent_id
START WITH t1.id = 1 
CONNECT BY PRIOR t1.id = t1.parent_id

Voulez-vous faire cela?

SELECT id, parent_id, name, 
 (select Name from tbl where id = t.parent_id) parent_name
FROM tbl t start with id = 1 CONNECT BY PRIOR id = parent_id

Edit Une autre option basée sur celle d'OMG (mais je pense que cela fonctionnera également):

select 
           t1.id, 
           t1.parent_id, 
           t1.name,
           t2.name AS parent_name,
           t2.id AS parent_id
from 
    (select id, parent_id, name
    from tbl
    start with id = 1 
    connect by prior id = parent_id) t1
    left join
    tbl t2 on t2.id = t1.parent_id




hierarchical-data