|
|
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
Ничего не понимаю: 1) какая связь с темой топика?? 2) а что Вы хотите - в одном случае Вы говорите построить дерево, потом отфильровать, а во втором случае наоборот?? ЗЫ: и зачем Вам ROWNUM и sys_connect_by_path? Чтобы было чем ответить на вопрос 1? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2007, 18:19 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
kosourпо базе, в которой нет пользователя UNKOWN_USER выдает тот же CONNECT BY WITHOUT FILTERING Hierarchical Queries ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2007, 21:43 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
2 Elic Извини, если достаю. ElicОтсюда парадокс: нам нужен rownum до фильтрации, но вычислен rownum может быть только после фильтрации, Разве возможность (не обязательно в иерархическом) запросе написать ...where rownum... уже не свидетельствует о том, что rownum получает значения до фильтрации? В частности, пока не отобрано ни одной записи, rownum=1? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 10:17 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
ModelR 2 Elic Извини, если достаю. ElicОтсюда парадокс: нам нужен rownum до фильтрации, но вычислен rownum может быть только после фильтрации, Разве возможность (не обязательно в иерархическом) запросе написать ...where rownum... уже не свидетельствует о том, что rownum получает значения до фильтрации? В частности, пока не отобрано ни одной записи, rownum=1? Этот фильтр (по rownum) применяется в последнюю очередь, когда все остальные уже отработали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 10:24 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
ModelRРазве возможность (не обязательно в иерархическом) запросе написать ...where rownum... уже не свидетельствует о том, что rownum получает значения до фильтрации? В частности, пока не отобрано ни одной записи, rownum=1?Т.е. Вы думаете, что Оракл может условие rownum >= выполнить до фильтрации? Т.е. получение Вами набора данных будет иметь случайный характер, зависящий от того попали ли "пронумерованные вначале" потом в фильтрацию? Сами подумайте - бред ведь :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 10:27 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. и Код: plaintext 1. 2. 3. 4. 5. Как это можно понять иначе чем, грубо говоря rownum = 1 Цикл по фильтруемым данным if where then {Выдать результат;rownum +=1 } Конец цикла ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 10:41 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
ModelRуже не свидетельствует о том, что rownum получает значения до фильтрации?Если бы в данном случае это было так, то какой результат должен бы по-твоему получиться? :) Попробуй развить свою мысль. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 10:47 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
Elicто какой результат должен бы по-твоему получиться? :)Ровно какой получился. Я был бы удивлен результату типа Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 11:55 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
ModelRМысль развил чуть выше. Ошибаюсь?Найди-ка место для sys_connect_by_path в своём псевдокоде :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 12:15 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
ElicНайди-ка место для sys_connect_by_path в своём псевдокоде :) по фильтруемым данным == по итератору дерева (в котором щелкают level и sys_coonect_by_xxxx) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 12:45 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
ModelR ElicНайди-ка место для sys_connect_by_path в своём псевдокоде :)по фильтруемым данным == по итератору дерева (в котором щелкают level и sys_coonect_by_xxxx)Всё. Спасибо. Теперь логику увидел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 13:06 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
Продолжаем извращаться: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. PATHRNORNUMPATH21122 33 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 13:14 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
Ну как, это поведение можно объяснить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 11:31 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
RA\/ENНу как, это поведение можно объяснить?Это поведение объясняется просто: аналитика и sys_connect_by_path вместе не живут :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 11:44 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
RA\/ENНу как, это поведение можно объяснить?Ну тут гарантированный парадокс: аналитика считается после фильтрации, её в путь никак не вставить :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 13:10 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
RA\/ENНу как, это поведение можно объяснить? Похоже на Bug 3564507 SYS_CONNECT_BY_PATH() RETURNS NO VALUE WHEN ANALYTIC SQL FN IN SAME QUERY ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 16:09 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
JannnyНичего не понимаю: 1) какая связь с темой топика?? 2) а что Вы хотите - в одном случае Вы говорите построить дерево, потом отфильровать, а во втором случае наоборот?? ЗЫ: и зачем Вам ROWNUM и sys_connect_by_path? Чтобы было чем ответить на вопрос 1? Нет, не для этого. Показалась нелогичным отложенная фильтрация строк запроса. Спасибо Apex за ссылку на TFM :) В моих запросах практически не используются иерархические запросы, зато очень болезнены вопросы фильтрации. На табличке в 10-100 млн строк промахнешься - мало не покажется. Поэтому мне казалось (хотелось :) ) чтобы оракл отбросил лишние строки как можно быстрее. Почитав FM понял что это частный случай, поэтому оракл реализовал другой подход. Все дальнейшее написано потому, что на форуме читателей гораздо больше писателей, поэтому может быть кому-то будет полезно. Для тех, кому это все тривиально - можно не читать :) Надеюсь, что ошибок мало :) Собственно, на бытовом языке эти два алгоритма звучат так: 1.(Хотелось) Возьми исходные строки, отфильтруй лишнее, построй дерево и выдай результат. 2.(На самом деле) Возьми исходные строки, построй дерево, отфильтруй лишнее, выдай результат. Причем, выдать результат надо как можно раньше. Т.е. если строка уже готова к выдаче(прошла фильтрацию), и все колонки могут быть вычислены - то они вычисляются, строка отправляются пользователю и идет дальнейшее построение дерева. В первом алгоритме результат может быть неполным, потому что при фильтрации строк могут быть потеряны некоторые промежуточные строки, из-за которых нижележащие в дереве уровни пропадут, хотя будут удовлетворять условиям фильтра. Например, Пусть есть таблица сотрудников компании из стандартного примера SCOTT.EMP. И нужно выбрать сотрудников, чье имя начинается на букву "J" . Код: plaintext 1. 2. 3. 4. является 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. перед выполнением запросов будем вызывать a#h.reset_id; Я немного дополнил исходный запрос Elic'a чтобы видно было этапы выполнения запроса: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. В колонке 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, '~') Для аналитической функции механизм обработки немного изменяется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 18:50 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
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. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. Если в условии соединения использовать prior и связь parent - child, то все работает по той же схеме. Например для дерева, состоящего из двух веток, выходящих из null. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 18:41 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, сортировка выполняется до "where" ps при написании запроса надо учитывать что оракля считает Any remaining WHERE clause predicates are evaluated. ..... stax ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 19:09 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
stax..сортировка выполняется до "where" Что? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 19:17 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopstax..сортировка выполняется до "where" Что? а когда по твоему ? соответственно и ровнум вычисляется после "иерархичной" сортировки ..... stax ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 19:45 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
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. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. А при использовании rownum на первый взягляд может показаться неожиданным, но по факту все довольно закономерно. Оракл сначала опускается на указанное число строк (и так получается, что уровней) из одного корня, потом переходит на другой корень и условие соединения сразу же становится ложным. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 22:10 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
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. Код: 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. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 22:27 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
И для сравнения 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. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 22:32 |
|
||
|
sys_connect_by_path(rownum) с фильтрацией
|
|||
|---|---|---|---|
|
#18+
SYdbms_photoshopНикакой сортировки по умолчанию не выполняется. Выполняется построение дерева методом обхода в глубину. Не путай DEPTH/BREADTH FIRST c ORDER SIBLINGS BYА почему ты решил, что я путаю и с каким из двух предложений ты не согласен? SYИ для сравнения ORDER SIBLINGS BY c ORDER BY в плане ROWNUMЭто тоже для меня? :) На основании чего сделан вывод, что мне это не очевидно? PS. Лучше б ты Станиславу отвечал на его некорректную реплику. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 23:35 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=34956362&tid=1886258]: |
0ms |
get settings: |
7ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
157ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 212ms |
| total: | 469ms |

| 0 / 0 |
