Вам нужен не l oop, а иерархический запрос . Взгляните на следующий пример, основанный на таблице EMP
Скотта.
Это его содержимое; сотрудники отображаются иерархически, показывая, чей начальник:
SQL> select level,
2 lpad(' ', level * 2, ' ') || e.ename name
3 from emp e
4 start with e.mgr is null
5 connect by prior e.empno= e.mgr;
LEVEL NAME
---------- ---------------
1 KING
2 JONES
3 SCOTT
4 ADAMS
3 FORD
4 SMITH
2 BLAKE
3 ALLEN
3 WARD
3 MARTIN
3 TURNER
3 JAMES
2 CLARK
3 MILLER
14 rows selected.
SQL>
Если вы хотите начать с середины таблицы (например, начиная с SMITH
), вы "перевернуть" его:
SQL> select level lvl,
2 lpad(' ', level * 2, ' ') || e.ename name
3 from emp e
4 start with e.ename = 'SMITH'
5 connect by prior e.mgr= e.empno;
LVL NAME
---------- ---------------
1 SMITH
2 FORD
3 JONES
4 KING
SQL>
Наконец, используя этот запрос в качестве CTE (или подзапроса, если ваша версия Forms не поддерживает CTE), выберите тот, чье имя имеет самый высокий уровень:
SQL> with temp as
2 (select level lvl,
3 lpad(' ', level * 2, ' ') || e.ename name
4 from emp e
5 start with e.ename = 'SMITH'
6 connect by prior e.mgr= e.empno
7 )
8 select trim(t.name) name
9 from temp t
10 where t.lvl = (select max(t1.lvl) from temp t1);
NAME
---------------
KING
SQL>
Или, еще лучше, используя connect_by_isleaf
:
SQL> select e.ename name
2 from emp e
3 where connect_by_isleaf = 1
4 start with e.ename = 'SMITH'
5 connect by prior e.mgr= e.empno;
NAME
---------------
KING
SQL>