Link to home
Start Free TrialLog in
Avatar of Mike Winichenko
Mike Winichenko

asked on

Please, explain strange behavior of connect by

Hello! There's a (stripped off version of real) SQL query. I understand its logic. I can't understand why it leaves only 2 records of level 1 after uncommenting AND...
Can anybody explain? (http://sqlfiddle.com/#!4/56df0e/17)
SELECT id,PRIOR id,level n
FROM(SELECT'aaa' AS id,2 AS ticket_cnt
     FROM dual
     UNION ALL
     SELECT 'bbb' AS id,4 AS ticket_cnt
     FROM dual
    )
CONNECT BY NOCYCLE (
    level <= ticket_cnt
    --AND id = PRIOR id
    )
ORDER BY    3   ,1   ,2;
And by the way, why there is cycle (comment off nocycle - you'll see)?
Avatar of slightwv (䄆 Netminder)
slightwv (䄆 Netminder)

You need the NOCYCLE because of the PRIOR statement.  Without the PRIOR, it doesn't really do anything.

The PRIOR you have creates a loop in the data. If you comment in the AND and remove NOCYCLE, you'll get an error:
ERROR at line 4:
ORA-01436: CONNECT BY loop in user data

Open in new window



From the docs:
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/Hierarchical-Query-Pseudocolumns.html#GUID-2F2FBA6F-2FD1-47D6-A74F-DB4B31E4D400
NOCYCLE enables Oracle to return the results of a query that would otherwise fail because of a CONNECT BY loop in the data.

>> can't understand why it leaves only 2 records of level 1 after uncommenting AND...

I'm not thinking it is just level=1.  It returns "if the current row has a child which is also its ancestor"

I got that phrase from the same doc link above for the CONNECT_BY_ISCYCLE Pseudocolumn .

You can see that if you add it to your query:
SELECT id,level n,ticket_cnt t, CONNECT_BY_ISCYCLE 
FROM(
	SELECT'aaa' AS id,2 AS ticket_cnt 
	FROM dual
		UNION ALL
	SELECT 'bbb' AS id,4 AS ticket_cnt
	FROM dual
)
CONNECT BY NOCYCLE
(
	level <= ticket_cnt
	AND id = PRIOR id
)
ORDER BY 1,2;

Open in new window


All that said, are you sure it is returning what you want?  I've not been successful using a column value in a connect by level like that.  My guess is the PRIOR and NOCYCLE is because without them, the query generated a LOT of unnecessary rows.
Nothing further to add. I endorse Slightnw's comments.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.