Oracle
 sql >> Base de données >  >> RDS >> Oracle

Confusion avec Oracle CONNECT BY

Comment un CONNECT BY la requête est exécutée et évaluée - étape par étape (par exemple).

Supposons que nous ayons le tableau suivant et une connexion par requête :

select * from mytable;

         X
----------
         1 
         2 
         3 
         4 

SELECT level, m.* 
FROM mytable m
START with x = 1
CONNECT BY PRIOR x +1 = x  OR  PRIOR x + 2 = x 
ORDER BY level;

Étape 1 :

Sélectionnez les lignes de la table mytable qui répondent à un START WITH condition, affectez LEVEL = 1 au jeu de résultats renvoyé :

 CREATE TABLE step1 AS
 SELECT 1 "LEVEL", X from mytable
 WHERE x = 1;

 SELECT * FROM step1;

         LEVEL          X
    ---------- ----------
             1          1

Étape 2

Augmenter le niveau de 1 :

LEVEL = LEVEL + 1

Joignez le jeu de résultats renvoyé à l'étape précédente avec mytable en utilisant CONNECT BY conditions comme conditions de jointure.

Dans cette clause PRIOR column-name fait référence au jeu de résultats renvoyé par l'étape précédente et au simple column-name fait référence à mytable tableau :

CREATE TABLE step2 AS
SELECT 2 "LEVEL", mytable.X from mytable
JOIN step1 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step2;

     LEVEL          X
---------- ----------
         2          2 
         2          3

ÉTAPE x+1

Répétez #2 jusqu'à ce que la dernière opération renvoie un jeu de résultats vide.

Étape 3

CREATE TABLE step3 AS
SELECT 3 "LEVEL", mytable.X from mytable
JOIN step2 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step3;

     LEVEL          X
---------- ----------
         3          3 
         3          4 
         3          4

Étape 4

CREATE TABLE step4 AS
SELECT 4 "LEVEL", mytable.X from mytable
JOIN step3 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step4;

     LEVEL          X
---------- ----------
         4          4 

Étape 5

CREATE TABLE step5 AS
SELECT 5 "LEVEL", mytable.X from mytable
JOIN step4 "PRIOR"
ON "PRIOR".x +1 = mytable.x or  "PRIOR".x + 2 = mytable.x;

select * from step5;

no rows selected

L'étape 5 n'a renvoyé aucune ligne. Nous finalisons donc la requête

Dernière étape

UNION ALL résultats de toutes les étapes et le renvoyer comme résultat final :

SELECT * FROM step1
UNION ALL
SELECT * FROM step2
UNION ALL
SELECT * FROM step3
UNION ALL
SELECT * FROM step4
UNION ALL

SELECT * FROM step5;

     LEVEL          X
---------- ----------
         1          1 
         2          2 
         2          3 
         3          3 
         3          4 
         3          4 
         4          4 

Appliquons maintenant la procédure ci-dessus à votre requête :

SELECT * FROM dual;

DUMMY
-----
X 

SELECT LEVEL FROM DUAL CONNECT BY rownum>5;

Étape 1

Puisque la requête ne contient pas le START WITH clause, Oracle sélectionne tous les enregistrements de la table source :

CREATE TABLE step1 AS
SELECT 1 "LEVEL" FROM dual;

select * from step1;

     LEVEL
----------
         1 

Étape 2

CREATE TABLE step2 AS
SELECT 2 "LEVEL" from dual
JOIN step1 "PRIOR"
ON rownum > 5

select * from step2;

no rows selected

La dernière étape n'ayant renvoyé aucune ligne, nous allons finaliser notre requête.

Dernière étape

SELECT * FROM step1
UNION ALL

SELECT * FROM step2;

     LEVEL
----------
         1

L'analyse de la dernière requête :

select level from dual connect by rownum<10;

Je vous laisse comme devoir.