Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

CONNECT BY with CROSS JOIN and WHERE not executing as described in doc

blamaApr 18 2013 — edited Apr 19 2013
Hello all,

please see these two statements. They are the same, but the 1st uses t1 INNER JOIN t2 while the snd uses a CROSS JOIN with WHERE.
The 2nd statement shows one row more than the first, but the CROSS JOIN with WHERE is the same as the INNER JOIN.

The result would be OK if Oracle did:
JOIN -> CONNECT BY PRIOR -> WHERE

But according to the docs it does:
JOIN (and WHEREs for JOINS) -> CONNECT BY PRIOR -> Rest of WHERE

See http://docs.oracle.com/cd/E11882_01/server.112/e26088/queries003.htm#SQLRF52332 for details. There it says:

Oracle processes hierarchical queries as follows:
A join, if present, is evaluated first, whether the join is specified in the FROM clause or with WHERE clause predicates.
The CONNECT BY condition is evaluated.
Any remaining WHERE clause predicates are evaluated.
+.....+

Is this a bug? I'd say yes, because it differs from the docs and it also is not what people are used to ("a,b WHERE" is the same as "a INNER JOIN b").

Thanks,
Blama

--Statement 1:
WITH t1
AS 
(SELECT 1 a, 2 b FROM DUAL UNION ALL 
SELECT 2 a, 3 b FROM DUAL UNION ALL
SELECT 3 a, 4 b FROM DUAL UNION ALL
SELECT 4 a, 5 b FROM DUAL UNION ALL
SELECT 5 a, 6 b FROM DUAL),
t2 AS
(SELECT 1 c FROM DUAL UNION ALL 
SELECT 2 c FROM DUAL UNION ALL
SELECT 3 c FROM DUAL UNION ALL
SELECT 5 c FROM DUAL)
SELECT DISTINCT t1.a, t2.c, t1.b, level, SYS_CONNECT_BY_PATH(t1.a, '/') Path
FROM t1 INNER JOIN t2
ON t1.a = t2.c
CONNECT BY t1.a = PRIOR t1.b
START WITH t1.a = 1
ORDER BY
1,2,3;

--Result:
--1	1	2	1	/1
--2	2	3	2	/1/2
--3	3	4	3	/1/2/3


--Statement 2:
WITH t1
AS 
(SELECT 1 a, 2 b FROM DUAL UNION ALL 
SELECT 2 a, 3 b FROM DUAL UNION ALL
SELECT 3 a, 4 b FROM DUAL UNION ALL
SELECT 4 a, 5 b FROM DUAL UNION ALL
SELECT 5 a, 6 b FROM DUAL),
t2 AS
(SELECT 1 c FROM DUAL UNION ALL 
SELECT 2 c FROM DUAL UNION ALL
SELECT 3 c FROM DUAL UNION ALL
SELECT 5 c FROM DUAL)
SELECT DISTINCT t1.a, t2.c, t1.b, level, SYS_CONNECT_BY_PATH(t1.a, '/') Path
FROM t1 CROSS JOIN t2
WHERE t1.a = t2.c
CONNECT BY t1.a = PRIOR t1.b
START WITH t1.a = 1
ORDER BY
1,2,3;

--Result:
--1	1	2	1	/1
--2	2	3	2	/1/2
--3	3	4	3	/1/2/3
--5	5	6	5	/1/2/3/4/5
My details:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE	11.2.0.2.0	Production
TNS for Solaris: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 17 2013
Added on Apr 18 2013
12 comments
622 views