Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursion In Oracle

I have the following table in an oracle:

Parent(arg1, arg2)

and I want the transitive closure of the relation parent. That is, I want the following table

Ancestor(arg1, arg2)

How is this possible in Oracle?

I am doing the following:

WITH Ancestor(arg1, arg2)  AS (

  SELECT p.arg1, p.arg2 from parent p
  UNION
  SELECT p.arg1 , a.arg2 from parent p,  Ancestor a 
  WHERE p.arg2 = a.arg1

)

SELECT DISTINCT * FROM Ancestor;

I get the error

*Cause:    column aliasing in WITH clause is not supported yet
*Action:   specify aliasing in defintion subquery and retry
Error at Line: 1 Column: 20

How can I solve this without column aliasing?

like image 841
myahya Avatar asked Jan 11 '11 16:01

myahya


People also ask

What is Oracle recursion?

Sometimes, to execute a SQL statement issued by a user, the Oracle Server must issue additional statements. Such statements are called recursive calls or recursive SQL statements.

What is recursion in PL SQL?

PL/SQL Recursive FunctionsWhen a subprogram calls itself, it is referred to as a recursive call and the process is known as recursion. To illustrate the concept, let us calculate the factorial of a number. Factorial of a number n is defined as − n! = n*(n-1)! = n*(n-1)*(n-2)! ... = n*(n-1)*(n-2)*(n-3)...

What is recursive CTE in Oracle?

Thus, a recursive CTE consists of a nonrecursive SELECT part followed by a recursive SELECT part. Each SELECT part can itself be a union of multiple SELECT statements. The types of the CTE result columns are inferred from the column types of the nonrecursive SELECT part only, and the columns are all nullable.

Does PL SQL support recursion?

I mean, can I use recursion to have a function call itself? Answer: Yes, PL/SQL does support recursion via function calls. Recursion is the act of a function calling itself, and a recursive call requires PL/SQL to create local copies of its memory structures for each call.


2 Answers

WITH    Ancestor(arg1, arg2) AS
        (
        SELECT  p.arg1, p.arg2
        FROM    parent p
        WHERE   arg2 NOT IN
        (
            SELECT  arg1
            FROM    parent
        )

        UNION ALL

        SELECT  p.arg1, a.arg2
        FROM    Ancestor a 
        JOIN    parent p
        ON      p.arg2 = a.arg1
        )
SELECT  *
FROM    Ancestor

Oracle only supports recursive CTE since 11g Release 2.

In earlier versions, use CONNECT BY clause:

SELECT  arg1, CONNECT_BY_ROOT arg2
FROM    parent
START WITH
        arg2 NOT IN
        (
        SELECT  arg1
        FROM    parent
        )
CONNECT BY
        arg2 = PRIOR arg1
like image 198
Quassnoi Avatar answered Oct 27 '22 05:10

Quassnoi


Oracle allows recursive queries. See: http://www.adp-gmbh.ch/ora/sql/connect_by.html

Of course, these usually assume the hierarchical data is all in one table. Splitting it into separate tables makes things complicated.

like image 28
FrustratedWithFormsDesigner Avatar answered Oct 27 '22 05:10

FrustratedWithFormsDesigner