Difference between a CROSS JOIN and a Cartesian product of the noted comma?

Hello everyone,

Oracle version: Oracle Database 11 g Enterprise Edition Release 11.2.0.1.0 - 64 bit
OS: Linux Fedora Core 17 (x86_64)

I was practicing on recursive subquery factoring based on oracle examples available in the documentation
http://docs.Oracle.com/CD/E11882_01/server.112/e26088/statements_10002.htm#i2129904

I was working on an example that displays the hierarchy of each manager with related employees. Here's how
WITH tmptab(empId, mgrId, lvl) AS
(
    SELECT  employee_id, manager_id, 0 lvl
    FROM employees
    WHERE manager_id IS NULL
    UNION ALL
    SELECT  employee_id, manager_id, lvl+1
    FROM employees, tmptab
    WHERE (manager_id = empId)
)
SEARCH DEPTH FIRST BY mgrId SET order1
SELECT LPAD(' ', lvl * 3, ' ') || empId AS empId
FROM tmptab;
Which gives the desired result
EMPID
---------------------
100
   101
      108
      109
      110
      111
      112
      113
      200
      203
      204
      205
      206
   102
      103
      104
      105
      106
      107
   114
      115
      116
      117
      118
      119
   120
      125
      126
      127
      128
      180
      181
      182
      183
   121
      129
      130
      131
      132
      184
      185
      186
      187
   122
      133
      134
      135
      136
      188
      189
      190
      191
   123
      137
      138
      139
      140
      192
      193
      194
      195
   124
      141
      142
      143
      144
      196
      197
      198
      199
   145
      150
      151
      152
      153
      154
      155
   146
      156
      157
      158
      159
      160
      161
   147
      162
      163
      164
      165
      166
      167
   148
      168
      169
      170
      171
      172
      173
   149
      174
      175
      176
      177
      178
      179
   201
      202

107 rows selected.

SQL> 
However, by chance, I noticed that if I put CROSS JOIN instead of put a comma between table names, the same query behaves differently.

In other words, if instead of writing
. . .
UNION ALL
    SELECT  employee_id, manager_id, lvl+1
    FROM employees, tmptab
    WHERE (manager_id = empId)
I am writing
. . .
UNION ALL
    SELECT  employee_id, manager_id, lvl+1
    FROM employees CROSS JOIN tmptab
    WHERE (manager_id = empId)
I get the following error message
ERROR at line 4:
ORA-32044: cycle detected while executing recursive WITH query
Any idea?
Correct me if I'm wrong, but I remember, oracle supports as many JOIN CROSSROADS notation for Cartesian product (vector product =). For example
SQL> WITH tmptab1 AS
  2  (
  3      SELECT 'a1' AS colval FROM DUAL UNION ALL
  4      SELECT 'a2' AS colval FROM DUAL UNION ALL
  5      SELECT 'a3' AS colval FROM DUAL
  6  ),
  7  tmptab2 AS
  8  (
  9      SELECT 'b1' AS colval FROM DUAL UNION ALL
 10      SELECT 'b2' AS colval FROM DUAL
 11  )
 12  SELECT t1.colval, t2.colval
 13  FROM tmptab1 t1 CROSS JOIN tmptab2 t2;

CO CO
-- --
a1 b1
a2 b1
a3 b1
a1 b2
a2 b2
a3 b2

6 rows selected.

SQL> LIST 13
 13* FROM tmptab1 t1 CROSS JOIN tmptab2 t2
SQL>
SQL>
SQL> CHANGE /CROSS JOIN/,
 13* FROM tmptab1 t1 , tmptab2 t2
SQL> 
SQL>
SQL> LIST
  1  WITH tmptab1 AS
  2  (
  3  SELECT 'a1' AS colval FROM DUAL UNION ALL
  4  SELECT 'a2' AS colval FROM DUAL UNION ALL
  5  SELECT 'a3' AS colval FROM DUAL
  6  ),
  7  tmptab2 AS
  8  (
  9  SELECT 'b1' AS colval FROM DUAL UNION ALL
 10  SELECT 'b2' AS colval FROM DUAL
 11  )
 12  SELECT t1.colval, t2.colval
 13* FROM tmptab1 t1 , tmptab2 t2
SQL> 
SQL> /

CO CO
-- --
a1 b1
a2 b1
a3 b1
a1 b2
a2 b2
a3 b2

6 rows selected.

SQL> 
So if the two rated commas and CROSS JOIN have the same semantics, why do I get a cycle mentioned above cites recursive subquery factoring while the same query works pretty well with comma between table instead of CROSS JOIN names? Because if a cycle is detected (= current element ancestor) it means that the product with the CROSS JOIN notation produces duplicates which are absent in the result of the Cartesian product rated comma.

I would appreciate it if you could kindly shed some light.

Thanks in advance,

Kind regards
Dariyoosh

Hello

dariyoosh wrote:
... Oracle terminology could become really confusing. But once again, according to the online glossary, a Cartesian product is apparently regarded as a join
http://docs.Oracle.com/CD/E11882_01/server.112/e25789/glossary.htm?type=popup#CNCPT44493
>

There is no doubt that a Cartesian product (also called cross join) is a join. If loops in a WITH recursive clause are detected after completing the joins, but before other conditions apply, the relevant question here is "what are the requirements to join?
In the ANSI syntax, the distinction is always clear. Join conditions occur in the... Clause WE

SELECT  employee_id, manager_id, lvl + 1
FROM      employees
JOIN        tmptab          ON  (manager_id = empId)     -- Join condition
;

and other conditions occur in the WHERE (or HAVING or CONNECT BY) clause.

SELECT  employee_id, manager_id, lvl + 1
FROM            employees
CROSS JOIN         tmptab
WHERE  (manager_id = empId)     -- NOT a join condition
;

In the joins of the former, it seems to be the case that any condition involving 2 or more tables (or the + indicator of outer join) is a condtion of join:

SELECT  employee_id, manager_id, lvl + 1
FROM      employees
,         tmptab
WHERE  (manager_id = empId)     -- Join condition
;

Tags: Database

Similar Questions

Maybe you are looking for