powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
13 сообщений из 13, страница 1 из 1
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39482617
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте! вопрос по теме.
К сож в доке не было указано, что нельзя использовать SYS_CONNECT_BY_PATH() в разделе WHERE, что даёт ORA-30002, function was called at places other than the SELECT list and ORDER BY clause.

Вопрос: хотелось бы, не заворачивая запрос в обёртку , оставить только ветки 1-4 и 1-4-5 Например, задать условие типа гипотетического
Код: plaintext
where  IF( lvl=2 and id=4) THEN lvl=3 and id=4 END
Как это проще сделать?

Пример запроса
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select tre.*, level as lvl, (CONNECT_BY_ROOT tre.id) as id_root
    , CONNECT_BY_ISLEAF as isleaf, CONNECT_BY_ISCYCLE iscycle
    , SYS_CONNECT_BY_PATH( tre.id, '/') as val
    from 
    (    select 1 as id, NULL as prev  from dual 
            union
        select 2 as id, 1 as prev from dual 
            union
        select 3 as id, 2 as prev from dual -- 1-2-3
            union
        select 4 as id, 1 as prev from dual -- 1-4
            union
        select 5 as id, 4 as prev from dual -- 1-4-5
    ) tre
where 2=2 --and level = 3
    START WITH prev IS NULL
    CONNECT BY nocycle PRIOR  id = prev
    order SIBLINGS by id

резалт:
Код: plaintext
1.
2.
3.
4.
5.
ID PREV  LVL ROOT LEAF CYCLE VAL
1  null   1    1    0    0    /1
2    1    2    1    0    0    /1/2
3    2    3    1    1    0    /1/2/3
4    1    2    1    0    0    /1/4
5    4    3    1    1    0    /1/4/5

2) неожиданно узнал, что лист дерева НЕ то же самое, что и в "_ISLEAF". Похожий вопрос: как бы его распознать, без обёртки?
Ну и без подзапросов тоже...
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39482635
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
exp98хотелось бы, не заворачивая запрос в обёртку , оставить только ветки 1-4 и 1-4-5 rec with
exp98неожиданно узнал, что лист дерева НЕ то же самое, что и в "_ISLEAF"_isleaf это именно лист когда речь идет про дерево. У графа такого понятия нет.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39482708
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
exp98,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select tre.*, level as lvl, (CONNECT_BY_ROOT tre.id) as id_root
    , CONNECT_BY_ISLEAF as isleaf, CONNECT_BY_ISCYCLE iscycle
    , SYS_CONNECT_BY_PATH( tre.id, '/') as val
    from 
    (    select 1 as id, NULL as prev  from dual 
            union
        select 2 as id, 1 as prev from dual 
            union
        select 3 as id, 2 as prev from dual -- 1-2-3
            union
        select 4 as id, 1 as prev from dual -- 1-4
            union
        select 5 as id, 4 as prev from dual -- 1-4-5
    ) tre
where 2=2 and level >=2
    START WITH prev IS NULL
    CONNECT BY nocycle PRIOR  id = prev AND (level =2 AND id=4 OR level <>2 )
    order SIBLINGS by id



?
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39482732
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ora601,

Да, учитывая, что логика завязана на конкретные уровни, в rec with необходимости нет.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39482961
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ora601, спасибо, здесь задать сам не догадался.
Извиняюсь, что с листьями попутал, там всё ок.

Вот так хотел. Судя по всему, START WITH выдаёт ещё и корневой уровень, поэтому фильтрую его в WHERE.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
select tre.*, level as lvl, (CONNECT_BY_ROOT tre.id) as id_root
    , CONNECT_BY_ISLEAF as isleaf, CONNECT_BY_ISCYCLE iscycle
    , SYS_CONNECT_BY_PATH( tre.id, '/') as val
    from 
    (    select 1 as id, NULL as prev  from dual 
            union
        select 2 as id, 1 as prev from dual -- 1-2
            union
        select 3 as id, 2 as prev from dual -- 1-2-3
            union
        select 4 as id, 1 as prev from dual -- 1-4
            union
        select 5 as id, 4 as prev from dual -- 1-4-5
            union
        select 6 as id, 1 as prev from dual -- 1-6
    ) tre
where 2=2 and prev IS NOT NULL
SYS_CONNECT_BY_PATH function is not allowed here
    START WITH prev IS NULL -- начать с листьев 
    CONNECT BY nocycle PRIOR  id = prev and (level = 2 and (id=4 or id=6) OR (level = 3 and id=5) 

Рекурсивный WITH (это имелось ввиду?) наверное универсальней.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39482963
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И ещё, внезапно перестал ИЕ реагировать на кнопку "Опубликовать", поэтому задержался с ответом. Спасибо.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483111
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На самом деле нужно не в последовательных уровнях, а через один, или 2, или 3.
Оказалось, что тогда нельзя разрывать уровни в условии. Для 2-го и 5-го уровней получилось типа такого:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
............
    CONNECT BY nocycle PRIOR  id = prev 
        and (
        level = 2  and id=4
        OR level between 3 and 4  -- сохраняет непрерывность уровней
        OR level=5 and id= 6 
        OR level>4   -- дальнейшие уровни
        )

Вопрос снят.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483113
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
exp98
Код: plsql
1.
2.
        OR level=5 and id= 6 
        OR level> 4   -- дальнейшие уровни

Уверен?
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483116
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
exp98Рекурсивный WITH (это имелось ввиду?) наверное универсальней.Набери в гугле recursive with oracle.
В нем бы возникала необходимость, если надо реализовать накопительные условия по нескольким уровням.
Например: ветка попадает в результат если встретились два айдишника, кратные 5.
Если же проверка выполняется для конкретных уровней - то лучше использовать connect by ибо он лучше по производительности.

exp98На самом деле нужно не в последовательных уровнях, а через один, или 2, или 3.
Оказалось, что тогда нельзя разрывать уровни в условии. Для 2-го и 5-го уровней получилось типа такого:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
............
    CONNECT BY nocycle PRIOR  id = prev 
        and (
        level = 2  and id=4
        OR level between 3 and 4  -- сохраняет непрерывность уровней
        OR level=5 and id= 6 
        OR level>4   -- дальнейшие уровни
        )

Вопрос снят.
Код: plsql
1.
... or level not in (2, 5)
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483562
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicexp98
Код: plsql
1.
2.
        OR level=5 and id= 6 
        OR level> 4   -- дальнейшие уровни

Уверен? глазастый), опечатушка, от другого варианта осталось, главное, что коммент верный. И как мне показалось, условия надо писать не только без разрывов, но и в порядке возрастания левела. Хотя может только показалось..
dbms_photoshop ... or level not in (2, 5) именно так у меня останавится на 2-м уровне. Пока рабочая гипотеза, что в условии левел должен возрастать монотонно.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483582
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic, вот работающий пример
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
select tre.*, level as lvl, (CONNECT_BY_ROOT tre.id) as id_root
    , CONNECT_BY_ISLEAF as isleaf, CONNECT_BY_ISCYCLE iscycle
    , SYS_CONNECT_BY_PATH( val, '/') as val2
    from 
    (    select 1 as id, NULL as prev, 1 as val  from dual UNION
        select 2 as id, 1 as prev, 2 as val  from dual  UNION -- 1-2 
        select 3 as id, 2 as prev, 3 as val  from dual  UNION -- 1-2-3
        select 8 as id, 3 as prev, 6 as val  from dual  UNION -- 1-2-3-7
        select 9 as id, 3 as prev, 7 as val  from dual  UNION -- 1-2-3-6
        select 4 as id, 1 as prev, 4 as val  from dual  UNION -- 1-4
        select 5 as id, 4 as prev, 5 as val  from dual  UNION -- 1-4-5
        select 7 as id, 5 as prev, 7 as val  from dual  UNION -- 1-4-5-7
        select 6 as id, 5 as prev, 6 as val  from dual  -- 1-4-5-6
    ) tre
where 2=2 --and level = 4  --and prev IS NOT NULL 
SYS_CONNECT_BY_PATH function is not allowed here
    START WITH prev IS NULL -- начать с листьев 
    CONNECT BY nocycle PRIOR  id = prev 
/**/    
        and (2=3
        -- Единый блок условий: взять левелы=4 с ... на 2-м левеле , у которых на 4-м левеле ...
        OR level=2 and val in (2,4)
        OR level between 3 and 3  -- сохраняет непрерывность уровней
        OR level=4 and val= 7 
        OR level>4              -- дальнейшие уровни
        )        
/**/    order SIBLINGS by id


Сейчас на 4-м оба раза берём 7. Неудобство получается уже если на 4-м нужно один раз 6, другой раз 7
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483687
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
exp98,

Если на 4-м надо учитывать айдишник на 2-м

Код: plaintext
prior prev

Но с каждым сообщением менее понятно что таки ты хочешь реализовать.
...
Рейтинг: 0 / 0
XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
    #39483725
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopс каждым сообщением менее понятно Не обращайте внимания, теперь уже просто играю с запросом, ничего не прося.

Дело было так.
У нас (в конторе) есть иерархич-ая таблица - одна такая всего. Начальная идея - не очень громоздкие фильтры веток "на лету" именно иерархич-им запросом без обёрток, подзапросов и вызовов хранимок. Сперва пример упростил неудачно, потом последовательно натыкался на грабли.

Сейчас в целом цель - пощупать возможности иерархич-ого запроса. Если упрусь в невозможное, придётся обернуть, а там уже по path, но тогда тексты запросов громоздкие.
Но это всё факультативно, и отсюда опечатки - я не многостаночник, да ещё ИЕ-11 внезапно стал часто не пропускать посты.

Вот сейчас хотелка получить таким способом только 2 ветки 4-го уровня 1-2-3-6, 1-4-5-7. Про ИД ничего неизвестно кроме того, что оно есть.

Вообще же в прошлом году ваял длинный запрс, где это дерево раскручивалось в промежуточный курсор. Витает мысль уменьшать этот курсор на лету. Баловство, да ...
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / XE11.2: иерархич запрос без обёртки - 1)фильтр по двум уровням 2)распознать лист дерева
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]