sql >> Database >  >> RDS >> Oracle

Verwarring met Oracle CONNECT BY

Hoe een CONNECT BY query wordt uitgevoerd en geëvalueerd - stap voor stap (per voorbeeld).

Stel dat we de volgende tabel hebben en een connect by query:

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;

Stap 1:

Selecteer rijen uit tabel mytable die voldoen aan een START WITH voorwaarde, wijs LEVEL =1 toe aan de geretourneerde resultatenset:

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

 SELECT * FROM step1;

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

Stap 2

Verhoog het niveau met 1:

LEVEL = LEVEL + 1

Word lid van de resultatenset die in de vorige stap is geretourneerd met mytable met behulp van CONNECT BY voorwaarden als de voorwaarden voor deelname.

In deze clausule PRIOR column-name verwijst naar de resultatenset die is geretourneerd door de vorige stap, en eenvoudige column-name verwijst naar de mytable tafel:

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

STAP x+1

Herhaal #2 totdat de laatste bewerking een lege resultaatset oplevert.

Stap 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

Stap 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 

Stap 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

Stap 5 leverde geen rijen op, dus nu ronden we de zoekopdracht af

Laatste stap

UNION ALL resultaten van alle stappen en retourneer het als het uiteindelijke resultaat:

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 

Laten we nu de bovenstaande procedure toepassen op uw vraag:

SELECT * FROM dual;

DUMMY
-----
X 

SELECT LEVEL FROM DUAL CONNECT BY rownum>5;

Stap 1

Aangezien de zoekopdracht niet de START WITH . bevat clausule, Oracle selecteert alle records uit de brontabel:

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

select * from step1;

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

Stap 2

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

select * from step2;

no rows selected

Aangezien de laatste stap geen rijen heeft opgeleverd, gaan we onze zoekopdracht afronden.

Laatste stap

SELECT * FROM step1
UNION ALL

SELECT * FROM step2;

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

De analyse van de laatste vraag:

select level from dual connect by rownum<10;

Ik laat het aan jou over als een huiswerkopdracht.



  1. CHARINDEX() vs PATINDEX() in SQL Server - Wat is het verschil?

  2. Hoe de MID()-functie werkt in MySQL

  3. Een titel toevoegen aan een formulierkoptekst in Microsoft Access

  4. Hoe ORA-00900 op te lossen?