sql >> Databasteknik >  >> RDS >> Oracle

Förvirring med Oracle CONNECT BY

Hur en CONNECT BY fråga exekveras och utvärderas - steg för steg (genom exempel).

Säg att vi har följande tabell och en anslutning via fråga:

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;

Steg 1:

Välj rader från tabellen mytable som uppfyller en START WITH villkor, tilldela LEVEL =1 till den returnerade resultatuppsättningen:

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

 SELECT * FROM step1;

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

Steg 2

Öka nivån med 1:

LEVEL = LEVEL + 1

Gå med i resultatuppsättningen som returnerades i föregående steg med mytable med CONNECT BY villkor som anslutningsvillkor.

I denna klausul PRIOR column-name refererar till resultatuppsättningen som returnerades av föregående steg, och enkelt column-name hänvisar till mytable tabell:

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

STEG x+1

Upprepa #2 tills den sista operationen returnerar en tom resultatuppsättning.

Steg 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

Steg 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 

Steg 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

Steg 5 gav inga rader, så nu slutför vi frågan

Sista steget

UNION ALL resultat av alla steg och returnera det som slutresultat:

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 

Låt oss nu tillämpa proceduren ovan på din fråga:

SELECT * FROM dual;

DUMMY
-----
X 

SELECT LEVEL FROM DUAL CONNECT BY rownum>5;

Steg 1

Eftersom frågan inte innehåller START WITH sats, väljer Oracle alla poster från källtabellen:

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

select * from step1;

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

Steg 2

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

select * from step2;

no rows selected

Eftersom det sista steget inte gav några rader, kommer vi att slutföra vår fråga.

Sista steget

SELECT * FROM step1
UNION ALL

SELECT * FROM step2;

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

Analysen av den senaste frågan:

select level from dual connect by rownum<10;

Jag lämnar till dig som en hemuppgift.



  1. Returnera en lista över partitionsscheman i SQL Server (T-SQL)

  2. Använder funktionen COALESCE för att göra värden separerade med kommatecken

  3. PostgreSQL:Unik överträdelse:7 FEL:dubblettnyckelvärde bryter mot unika begränsningar users_pkey

  4. Hur DEGREES() fungerar i MariaDB