powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / sys_connect_by_path(rownum) с фильтрацией
25 сообщений из 54, страница 2 из 3
sys_connect_by_path(rownum) с фильтрацией
    #34956362
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ничего не понимаю:
1) какая связь с темой топика??
2) а что Вы хотите - в одном случае Вы говорите построить дерево, потом отфильровать, а во втором случае наоборот??

ЗЫ: и зачем Вам ROWNUM и sys_connect_by_path? Чтобы было чем ответить на вопрос 1?
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34956792
Фотография Apex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kosourпо базе, в которой нет пользователя UNKOWN_USER
выдает тот же
CONNECT BY WITHOUT FILTERING
Hierarchical Queries
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957338
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Elic
Извини, если достаю. ElicОтсюда парадокс: нам нужен rownum до фильтрации, но вычислен rownum может быть только после фильтрации, Разве возможность (не обязательно в иерархическом) запросе написать ...where rownum... уже не свидетельствует о том, что rownum получает значения до фильтрации? В частности, пока не отобрано ни одной записи, rownum=1?
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957358
Фотография Apex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelR 2 Elic
Извини, если достаю. ElicОтсюда парадокс: нам нужен rownum до фильтрации, но вычислен rownum может быть только после фильтрации, Разве возможность (не обязательно в иерархическом) запросе написать ...where rownum... уже не свидетельствует о том, что rownum получает значения до фильтрации? В частности, пока не отобрано ни одной записи, rownum=1?
Этот фильтр (по rownum) применяется в последнюю очередь, когда все остальные уже отработали.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957368
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelRРазве возможность (не обязательно в иерархическом) запросе написать ...where rownum... уже не свидетельствует о том, что rownum получает значения до фильтрации? В частности, пока не отобрано ни одной записи, rownum=1?Т.е. Вы думаете, что Оракл может условие rownum >= выполнить до фильтрации? Т.е. получение Вами набора данных будет иметь случайный характер, зависящий от того попали ли "пронумерованные вначале" потом в фильтрацию? Сами подумайте - бред ведь :)
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957411
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
with t as
(select  10  nom,  'A10' name from dual union ALL
 select  40  nom,  'A40' name from dual union ALL
 select  30  nom,  'A30' name from dual union ALL
 select  20  nom,  'A20' name from dual )
select name from t where rownum*nom =  40 
NAME A40 A20
и
Код: plaintext
1.
2.
3.
4.
5.
with t as
(select  10  nom,  'A10' name from dual union
 select  40  nom,  'A40' name from dual union
 select  30  nom,  'A30' name from dual union
 select  20  nom,  'A20' name from dual )
select name from t where rownum*nom =  40 
NAME A40
Как это можно понять иначе чем, грубо говоря
rownum = 1
Цикл по фильтруемым данным
if where then {Выдать результат;rownum +=1 }
Конец цикла
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957433
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelRуже не свидетельствует о том, что rownum получает значения до фильтрации?Если бы в данном случае это было так, то какой результат должен бы по-твоему получиться? :)
Попробуй развить свою мысль.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957693
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicто какой результат должен бы по-твоему получиться? :)Ровно какой получился.
Я был бы удивлен результату типа
Код: plaintext
~NULL~NULL~ 1 
Мысль развил чуть выше. Ошибаюсь?
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957788
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelRМысль развил чуть выше. Ошибаюсь?Найди-ка место для sys_connect_by_path в своём псевдокоде :)
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34957926
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicНайди-ка место для sys_connect_by_path в своём псевдокоде :)
по фильтруемым данным == по итератору дерева (в котором щелкают level и sys_coonect_by_xxxx)
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34958011
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelR ElicНайди-ка место для sys_connect_by_path в своём псевдокоде :)по фильтруемым данным == по итератору дерева (в котором щелкают level и sys_coonect_by_xxxx)Всё. Спасибо. Теперь логику увидел.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34958046
Фотография RA\/EN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Продолжаем извращаться:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select * from
( select sys_connect_by_path(rownum, '~') as path ,
         row_number() over (order by rownum) rno,
         rownum rnum,
         sys_connect_by_path(row_number() over (order by rownum), '~') path2
    from dual
    where mod(level,  3 ) =  0 
    connect by level <=  10 
)

PATHRNORNUMPATH21122 33
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34960588
Фотография RA\/EN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну как, это поведение можно объяснить?
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34960640
Jannny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RA\/ENНу как, это поведение можно объяснить?Это поведение объясняется просто: аналитика и sys_connect_by_path вместе не живут :)
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34961015
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RA\/ENНу как, это поведение можно объяснить?Ну тут гарантированный парадокс: аналитика считается после фильтрации, её в путь никак не вставить :)
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34961808
kosour
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
RA\/ENНу как, это поведение можно объяснить?

Похоже на Bug 3564507
SYS_CONNECT_BY_PATH() RETURNS NO VALUE WHEN ANALYTIC SQL FN IN SAME QUERY
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #34962297
kosour
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JannnyНичего не понимаю:
1) какая связь с темой топика??
2) а что Вы хотите - в одном случае Вы говорите построить дерево, потом отфильровать, а во втором случае наоборот??

ЗЫ: и зачем Вам ROWNUM и sys_connect_by_path? Чтобы было чем ответить на вопрос 1?

Нет, не для этого. Показалась нелогичным отложенная фильтрация строк запроса. Спасибо Apex за
ссылку на TFM :) В моих запросах практически не используются иерархические запросы, зато очень
болезнены вопросы фильтрации.

На табличке в 10-100 млн строк промахнешься - мало не покажется.
Поэтому мне казалось (хотелось :) ) чтобы оракл отбросил лишние строки как можно быстрее.
Почитав FM понял что это частный случай, поэтому оракл реализовал другой подход.

Все дальнейшее написано потому, что на форуме читателей гораздо больше писателей, поэтому
может быть кому-то будет полезно. Для тех, кому это все тривиально - можно не читать :)


Надеюсь, что ошибок мало :)

Собственно, на бытовом языке эти два алгоритма звучат так:
1.(Хотелось) Возьми исходные строки, отфильтруй лишнее, построй дерево и выдай результат.
2.(На самом деле) Возьми исходные строки, построй дерево, отфильтруй лишнее, выдай результат.

Причем, выдать результат надо как можно раньше. Т.е. если строка уже готова к выдаче(прошла фильтрацию),
и все колонки могут быть вычислены - то они вычисляются, строка отправляются пользователю и идет дальнейшее
построение дерева.

В первом алгоритме результат может быть неполным, потому что при фильтрации строк могут быть
потеряны некоторые промежуточные строки, из-за которых нижележащие в дереве уровни пропадут,
хотя будут удовлетворять условиям фильтра.

Например, Пусть есть таблица сотрудников компании из стандартного примера SCOTT.EMP. И нужно
выбрать сотрудников, чье имя начинается на букву "J" .

Код: plaintext
1.
2.
3.
4.
select empno, ename, level, sys_connect_by_path(ename,'->') as p from scott.emp
where ename like 'J%'
start with mgr is null
connect by mgr = prior empno 
Если бы оракл действовал по этому алгритму, то он бы потерял JAMES, у которого менеджером
является BLAKE, чье имя не начинается на букву J.

собственно, правильный алгоритм описан в доке, на которую указал APEX.

Теперь собственно, к теме топика :)
В принципе, ModelR правильно указал на алгоритм, который приводит к такому неочевидному результату.
Мне захотелось потдвердить это на тестовом примере.
Кстати, он же помог понять как работает этот запрос в случае аналитических функций.


Для того, чтобы понять в каком порядке выполняется запрос, нужна вспомогательная функция,
которая будет давать всякий раз новое значение. Sequence для этого не подходит, потому что в
переделах строки не изменяется.

Код: plaintext
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.
28.
create or replace package a#h 
is
function get_id return integer;
procedure reset_id;
end a#h;

create or replace package body a#h 
is
cnt integer;
function get_id return integer
is
begin 
cnt:= cnt +  1 ;
return cnt;
end get_id;

/*
Сбрасываем переменную в 0, чтобы получать воспроизводимый результат
в тестовых запросах 
*/
procedure reset_id is
begin
  cnt :=  0 ;
end  reset_id; 

begin
cnt :=  0 ;
end a#h;

перед выполнением запросов будем вызывать a#h.reset_id;

Я немного дополнил исходный запрос Elic'a чтобы видно было этапы выполнения запроса:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select begin_id, end_id, rnum, path_id, path_r from (
select a#h.get_id as end_id, a.* from
( select b.*, rownum as rnum
          , sys_connect_by_path(a#h.get_id, '~') as path_id
          , sys_connect_by_path(rownum, '~') as path_r
          from (select a#h.get_id as begin_id from dual ) b
    where mod(level,  3 ) = 0  and a#h.get_id  > - 1 
     start with a#h.get_id = 1 
    connect by level <=  10  and a#h.get_id  > - 2 
) a
)

В колонке PATH_ID хранится путь к корню дерева, причем, номер отражает реальный номер строки источника - до фильтрации.

Он возвращает следующий результат:
BEGIN_IDEND_IDRNUMPATH_IDPATH_R891~2~4~6~1~1~117182~2~4~6~11~13~15~1~1~1~2~2~226273~2~4~6~11~13~15~20~22~24~1~1~1~2~2~2~3~3~3



Теперь можно видеть, что запрос выполняется следующим образом:

Первая строка - номер, с которым строка будет выдана пользователю. Как и говорил ModelR, rownum
всякий раз увеличивается после выдачи строки пользователю. Т.е. rownum в процесс выполнения
запроса можно трактовать как "Сейчас готовится к выдаче строка с номером Rownum"

Цифры в ячейках означают номер шага выполнения алгоритмы. Цифра в скобках означает сколько
раз с начала запроса была вызвана функция a#h.get_id

Rownum11111111222222223333333344Level1122333344556666778899991010select begin_id, end_id, rnum, path_id, path_r from (10(8)11(9)21(17)22(18)32(26)33(27)select a#h.get_id as end_id, a.* from( select b.*, rownum as rnumВзять упорядоченный список родителей и добавить туда себя для функции sys_connect_by_path(a#h.get_id, '~')2(2)5(4)8(6)13(11)16(13)19(15)24(20)27(22)30(24)35(29) , sys_connect_by_path(a#h.get_id, '~') as path_id , sys_connect_by_path(rownum, '~') as path_r from (select a#h.get_id as begin_id from dual ) b where mod(level, 3) =0 and a#h.get_id > -13(2)6(4)9(7)14(11)17(13)20(16)25(20)28(22)31(25)36(29) start with a#h.get_id =11(1) connect by level <= 10 and a#h.get_id > -24(3)7(5)12(10)15(12)18(14)23(19)26(21)29(23)34(28)) a)

Несколько комментариев:
1. На шагах 3,6 счетчик вызовов функции a#h.get_id не меняется, так как имеет место быть быстрое
вычисление логического выражения: так как mod(level, 3) =0 - FALSE, то вторую часть вычислять не надо. На шаге 9, mod(level, 3) =0 - TRUE и поэтому вычисляем второе условие and a#h.get_id > -1
2. Судя по всему, Оракл ленив, и вызывает вычисление функции только при крайней необходимости.
Поэтому, например, begin_id и end_id вычисляются для строки самыми последними -
непосредственно, перед выдачей строки клиенту.
3. Из приведенного примера неясно в какой момент вызывается функция sys_connect_by_path - в
процессе обработки каждой строки, в виде, например выражения:

result := result ||delimiter||current_expression, где current_expression - значение аргумента функции для этой строки.

Либо при проходе по дереву формируется как-то список родителей, включая себя, а
непосредственно перед выдачей уже присходит обработка этого списка и превращение в строку
результата.

4. Как видно из пример, фильтрация происходит после обработки строки и в случае успеха, строка
отдается на формирование внешнего вида и выдачи, а в случае неуспеха - просто идет переход к
следующей строки в дереве. Поэтому такие странные значения стоят в выводе функции
sys_connect_by_path(rownum, '~')

Для аналитической функции механизм обработки немного изменяется.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
sys_connect_by_path(rownum) с фильтрацией
    #39421031
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicПуть должен быть сформирован на наборе данных до фильтрации.
Отсюда парадоксЕсли не делать озвученного допущения, то и парадоксов не будет.
Не совсем понятно из чего следует, что он должен? sys_connect_by_path не может быть использован в where.

Другое дело, пример хорош тем, что показывает, что, вероятно, не стоит разделять герерацию rownum/level и выполнение разных частей запроса.

В доке сказано
http://docs.oracle.com/cd/E11882_01/server.112/e41084/queries003.htm 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.Тут стоит уточнить, что если в where есть rownum/level то это выясиляется не перед/после, а во время постоения иерархии.

level генерится при переходе на новый уровень
rownum генерится попадании новой строки в результирующий recordset

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'),'~') as path_rn,
       replace(sys_connect_by_path(level, '~'),'~') as path_lvl
  from dual
 where mod(level, 3) = 0
connect by level < 10;
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'),'~') as path_rn,
       replace(sys_connect_by_path(level, '~'),'~') as path_lvl
  from dual
 where mod(level, 3) = 0
connect by rownum < 10;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        RN        LVL PATH_RN                        PATH_LVL                                          
---------- ---------- ------------------------------ --------------------------------------------------
         1          3 111                            123                                               
         2          6 111222                         123456                                            
         3          9 111222333                      123456789                                         

3 rows selected.

        RN        LVL PATH_RN                        PATH_LVL                                          
---------- ---------- ------------------------------ --------------------------------------------------
         1          3 111                            123                                               
         2          6 111222                         123456                                            
         3          9 111222333                      123456789                                         
         4         12 111222333444                   123456789101112                                   
         5         15 111222333444555                123456789101112131415                             
         6         18 111222333444555666             123456789101112131415161718                       
         7         21 111222333444555666777          123456789101112131415161718192021                 
         8         24 111222333444555666777888       123456789101112131415161718192021222324           
         9         27 111222333444555666777888999    123456789101112131415161718192021222324252627     

9 rows selected.



Если в условии соединения использовать prior и связь parent - child, то все работает по той же схеме.
Например для дерева, состоящего из двух веток, выходящих из null.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
with t as
(
select rownum id, rownum - 1 id_parent from dual connect by level <= 10
union all
select 1000 + rownum id, 1000 + rownum - 1 id_parent from dual connect by level <= 10
union all
select 0, null from dual
union all
select 1000, null from dual
)
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       sys_connect_by_path(id, '~') path_id
  from t
 where mod(level, 3) = 0
start with id_parent is null
connect by prior id = id_parent;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
        RN        LVL PATH_RN         PATH_LVL        PATH_ID                                           
---------- ---------- --------------- --------------- --------------------------------------------------
         1          3 111             123             ~0~1~2                                            
         2          6 111222          123456          ~0~1~2~3~4~5                                      
         3          9 111222333       123456789       ~0~1~2~3~4~5~6~7~8                                
         4          3 444             123             ~1000~1001~1002                                   
         5          6 444555          123456          ~1000~1001~1002~1003~1004~1005                    
         6          9 444555666       123456789       ~1000~1001~1002~1003~1004~1005~1006~1007~1008     

6 rows selected.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421045
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop,

сортировка выполняется до "where"

ps
при написании запроса надо учитывать что оракля считает Any remaining WHERE clause predicates are evaluated.

.....
stax
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421049
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..сортировка выполняется до "where" Что?
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421057
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopstax..сортировка выполняется до "where" Что?
а когда по твоему ?

соответственно и ровнум вычисляется после "иерархичной" сортировки

.....
stax
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421085
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..,

Никакой сортировки по умолчанию не выполняется.
Выполняется построение дерева методом обхода в глубину.

Более конкретным языком
http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm Oracle returns the rows in the order shown in Figure 9-1. In the diagram, children appear below their parents. For an explanation of hierarchical trees, see Figure 3-1, "Hierarchical Tree".
Тут можно привести следующий интересный пример.

Если в "генераторе" не одна строка, а больше, то при использовании level в условии соединения результат вполне ожидаем.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
with t as (select 1 id from dual union select 0 from dual)
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       t.*
  from t
connect by level <= 2;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
        RN        LVL PATH_RN         PATH_LVL                ID
---------- ---------- --------------- --------------- ----------
         1          1 1               1                        0
         2          2 12              12                       0
         3          2 13              12                       1
         4          1 4               1                        1
         5          2 45              12                       0
         6          2 46              12                       1

6 rows selected.


А при использовании rownum на первый взягляд может показаться неожиданным, но по факту все довольно закономерно.
Оракл сначала опускается на указанное число строк (и так получается, что уровней) из одного корня, потом переходит на другой корень и условие соединения сразу же становится ложным.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with t as (select 1 id from dual union select 0 from dual)
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       t.*
  from t
connect by rownum <= 5;
with t as (select 1 id from dual union select 0 from dual)
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       t.*
  from t
connect by rownum <= 6;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
        RN        LVL PATH_RN         PATH_LVL                ID
---------- ---------- --------------- --------------- ----------
         1          1 1               1                        0
         2          2 12              12                       0
         3          3 123             123                      0
         4          4 1234            1234                     0
         5          5 12345           12345                    0
         6          1 6               1                        1

6 rows selected.

        RN        LVL PATH_RN         PATH_LVL                ID
---------- ---------- --------------- --------------- ----------
         1          1 1               1                        0
         2          2 12              12                       0
         3          3 123             123                      0
         4          4 1234            1234                     0
         5          5 12345           12345                    0
         6          6 123456          123456                   0
         7          1 7               1                        1

7 rows selected.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421088
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop
Никакой сортировки по умолчанию не выполняется.
Выполняется построение дерева методом обхода в глубину.


Не путай DEPTH/BREADTH FIRST c ORDER SIBLINGS BY:

Код: 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.
28.
29.
30.
31.
with t as
(
select rownum id, rownum - 1 id_parent from dual connect by level <= 10
union all
select 1000 + rownum id, 1000 + rownum - 1 id_parent from dual connect by level <= 10
union all
select 0, null from dual
union all
select 1000, null from dual
)
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       sys_connect_by_path(id, '~') path_id
  from t
 where mod(level, 3) = 0
start with id_parent is null
connect by prior id = id_parent;


        RN        LVL PATH_RN         PATH_LVL        PATH_ID
---------- ---------- --------------- --------------- ---------------------------------------------
         1          3 111             123             ~0~1~2
         2          6 111222          123456          ~0~1~2~3~4~5
         3          9 111222333       123456789       ~0~1~2~3~4~5~6~7~8
         4          3 444             123             ~1000~1001~1002
         5          6 444555          123456          ~1000~1001~1002~1003~1004~1005
         6          9 444555666       123456789       ~1000~1001~1002~1003~1004~1005~1006~1007~1008

6 rows selected.



Код: 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.
28.
29.
30.
31.
with t as
(
select rownum id, rownum - 1 id_parent from dual connect by level <= 10
union all
select 1000 + rownum id, 1000 + rownum - 1 id_parent from dual connect by level <= 10
union all
select 0, null from dual
union all
select 1000, null from dual
)
select rownum rn,
       level lvl,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       sys_connect_by_path(id, '~') path_id
  from t
 where mod(level, 3) = 0
start with id_parent is null
connect by prior id = id_parent
order siblings by id desc;

        RN        LVL PATH_RN         PATH_LVL        PATH_ID
---------- ---------- --------------- --------------- ---------------------------------------------
         1          3 111             123             ~1000~1001~1002
         2          6 111222          123456          ~1000~1001~1002~1003~1004~1005
         3          9 111222333       123456789       ~1000~1001~1002~1003~1004~1005~1006~1007~1008
         4          3 444             123             ~0~1~2
         5          6 444555          123456          ~0~1~2~3~4~5
         6          9 444555666       123456789       ~0~1~2~3~4~5~6~7~8

6 rows selected.



SY.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421091
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И для сравнения ORDER SIBLINGS BY c ORDER BY в плане ROWNUM:

Код: 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.
28.
29.
30.
31.
32.
33.
34.
with t as
(
select rownum id, rownum - 1 id_parent from dual connect by level <= 10
union all
select 1000 + rownum id, 1000 + rownum - 1 id_parent from dual connect by level <= 10
union all
select 0, null from dual
union all
select 1000, null from dual
)
select rownum rn,
       level lvl,
       id,
       replace(sys_connect_by_path(rownum, '~'), '~') as path_rn,
       replace(sys_connect_by_path(level, '~'), '~') as path_lvl,
       sys_connect_by_path(id, '~') path_id
  from t
 where mod(level, 3) = 0
start with id_parent is null
connect by prior id = id_parent
order by id desc;

        RN        LVL         ID PATH_RN         PATH_LVL        PATH_ID
---------- ---------- ---------- --------------- --------------- ---------------------------------------------
         6          9       1008 444555666       123456789       ~1000~1001~1002~1003~1004~1005~1006~1007~1008
         5          6       1005 444555          123456          ~1000~1001~1002~1003~1004~1005
         4          3       1002 444             123             ~1000~1001~1002
         3          9          8 111222333       123456789       ~0~1~2~3~4~5~6~7~8
         2          6          5 111222          123456          ~0~1~2~3~4~5
         1          3          2 111             123             ~0~1~2

6 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
sys_connect_by_path(rownum) с фильтрацией
    #39421100
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYdbms_photoshopНикакой сортировки по умолчанию не выполняется.
Выполняется построение дерева методом обхода в глубину.


Не путай DEPTH/BREADTH FIRST c ORDER SIBLINGS BYА почему ты решил, что я путаю и с каким из двух предложений ты не согласен?
SYИ для сравнения ORDER SIBLINGS BY c ORDER BY в плане ROWNUMЭто тоже для меня? :)
На основании чего сделан вывод, что мне это не очевидно?

PS. Лучше б ты Станиславу отвечал на его некорректную реплику.
...
Рейтинг: 0 / 0
25 сообщений из 54, страница 2 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / sys_connect_by_path(rownum) с фильтрацией
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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