Oracle SQL может выполнять иерархические запросы с v2, используя свой собственный синтаксис CONNECT BY. В своем последнем релизе 11g 2 они добавили рекурсивный факторинг подзапроса, также известный как рекурсивный с предложением. Это стандарт ANSI, и, если я правильно понимаю, этот был реализован другими поставщиками РСУБД.
При сравнении соединения с рекурсивным с, я заметил разницу в наборе результатов при использовании определения цикла. Сопряжение по результатам более интуитивно для меня, поэтому мне интересно, если в реализации Oracle есть ошибка, или если это стандартное ANSI и ожидаемое поведение. Поэтому мой вопрос заключается в том, можно ли проверить рекурсивный запрос с помощью других баз данных, таких как MySQL, DB2, SQL Server и другие. Если эти базы данных, конечно, поддерживают рекурсивную с предложением.
Вот как это работает на Oracle 11.2.0.1.0
SQL> select *
2 from t
3 /
ID PARENT_ID
---------- ----------
1 2
2 1
2 rows selected.
Запрос с использованием синтаксиса CONNECT BY:
SQL> select id
2 , parent_id
3 , connect_by_iscycle
4 from t
5 connect by nocycle parent_id = prior id
6 start with id = 1
7 /
ID PARENT_ID CONNECT_BY_ISCYCLE
---------- ---------- ------------------
1 2 0
2 1 1
2 rows selected.
Что выглядит интуитивно для меня. Однако, используя новый синтаксис ANSI, он возвращает еще одну строку:
SQL> with tr (id,parent_id) as
2 ( select id
3 , parent_id
4 from t
5 where id = 1
6 union all
7 select t.id
8 , t.parent_id
9 from t
10 join tr on t.parent_id = tr.id
11 ) cycle id set is_cycle to '1' default '0'
12 select id
13 , parent_id
14 , is_cycle
15 from tr
16 /
ID PARENT_ID I
---------- ---------- -
1 2 0
2 1 0
1 2 1
3 rows selected.
Это script, который вы можете использовать для проверки:
create table t
( id number
, parent_id number
);
insert into t values (1, 2);
insert into t values (2, 1);
commit;
with tr (id,parent_id) as
( select id
, parent_id
from t
where id = 1
union all
select t.id
, t.parent_id
from t
join tr on t.parent_id = tr.id
) cycle id set is_cycle to '1' default '0'
select id
, parent_id
, is_cycle
from tr;