|
|
|
Вопрос по connect by
|
|||
|---|---|---|---|
|
#18+
Ребята всем привет! Можете пояснить алгоритм работы иерархических запросов? В частности следующий пример: Код: plsql 1. 2. 3. 4. 5. Возвращает то, что я и ожидал: одна запись выводится два раза по иерархии (1*2) = 2 NameLevelTom1Tom2 Далее добавляю еще одну запись (кортеж) в таблицу и выполняю тот же запрос. По моим ожиданиям: первым делом выполняется выборка из таблицы, далее к ней применяется условие в Connect by. Причем, так как не указан root, то родительской считается каждая запись. Т.е. для каждой записи будет возвращено две записи в соответствии с условием Connect by. Т.е я ожидаю что вернется: 1*2 + 1*2 = 4 записи. Но вернулось: Код: plsql 1. 2. 3. 4. 5. 6. 7. NameLevelJerry1Jerry2Tom2Tom1Jerry2Tom2 Вернулось 6 записей! Можете пояснить почему ? И как шел алгоритм? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2017, 17:15 |
|
||
|
Вопрос по connect by
|
|||
|---|---|---|---|
|
#18+
SQL_boyернулось 6 записей! Можете пояснить почему ? И как шел алгоритм?Все являются детьми всех. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2017, 17:28 |
|
||
|
Вопрос по connect by
|
|||
|---|---|---|---|
|
#18+
SQL_boyВернулось 6 записей! Можете пояснить почему ? И как шел алгоритм? Для начала следует осознать, что Вы не указали условия соединения. По аналогии с декартовым произведением, connect by в этих условиях пытается соединять всех со всеми. Итого: 2 записи level 1 и по два чилда level 2 у каждой. 2*(1+2)=6 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2017, 17:28 |
|
||
|
Вопрос по connect by
|
|||
|---|---|---|---|
|
#18+
andrey_anonymousSQL_boyВернулось 6 записей! Можете пояснить почему ? И как шел алгоритм? Для начала следует осознать, что Вы не указали условия соединения. По аналогии с декартовым произведением, connect by в этих условиях пытается соединять всех со всеми. Итого: 2 записи level 1 и по два чилда level 2 у каждой. 2*(1+2)=6 Ребята спасибо за ответы! Вроде сначала посчитал, что понял. А начал проверять и понял, что не понял =) Сейчас озвучу свой ход мысли и параллельно вопросы, возникшие в процессе. Есть таблица(отношение), содержащая две записи(кортежа). Применяем к ней выборку с connect by: Код: plsql 1. 2. 3. 4. 5. 6. 7. Итак, в соответствии с оракловой докой: Oracle1) Oracle selects the root row(s) of the hierarchy--those rows that satisfy the START WITH condition. 2) Oracle selects the child rows of each root row. Each child row must satisfy the condition of the CONNECT BY condition with respect to one of the root rows. Так как в запросе явно не указано, какая запись является родительской (root), то считаем все записи root-ами. Код: plsql 1. 2. Берем первую запись - 'Tom', она у нас root и, как понимаю условия соединения CONNECT BY к ней не применяется (поправьте если не так), а применяется это условие ко всем последующим записям. В нашем случае берем следующую запись Jerry и уже к ней применяем условие connect by level<=2. Вот здесь я думал, что выполняется реляционная операция - произведение(декартово): Jerry * 2 (т.к.connect by level<=2). В итоге получаем отношение из двух кортежей. Т.е у нас получается одна запись root - Tom (level=1), плюс два его потомка (две записи Jerry level 2), Итого три записи: Name Level'Tom'1'Jerry'2'Jerry'2 Далее переходит к второй root записи - Jerry и алгоритм повторяется. Получаем также три записи: Name Level'Jerry'1'Tom'2'Tom'2 На выходе получаем результат, который я приводил в первом посте этой темы: Name LevelJerry 1Jerry 2Tom 2Tom 1Jerry 2Tom 2 Потом я решил переписать условие connect by, вместо 2 поставил 3: Код: plsql 1. 2. 3. 4. 5. 6. 7. Я ожидал, что вернется 8 записей: (Tom (root) + 3 потомка (Jerry)) + (Jerry(root) + 3 потомка Tom). Но результат был такой: Name LevelJerry 1Jerry 2Jerry 3Tom 3Tom 2Jerry 3Tom 3Tom 1Jerry 2Jerry 3Tom 3Tom 2Jerry 3Tom 3 14 записей! Что-то не так я понял, алгоритм мой был ошибочный! Что не так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.09.2017, 14:05 |
|
||
|
Вопрос по connect by
|
|||
|---|---|---|---|
|
#18+
SQL_boy, Еще раз, у тебя нет отношения родитель - потомок в условии соединения (оператор PRIOR), соответсвенно когда выполняется переход на новый уровень все записи в таблице соответствуют условию соединения. Переход на новый уровень выполняется пока не будет построено два уровня. При переходе на новый уровень все записи таблицы являются детьми всех узлов уровня. Когда это осознаешь - можешь переходить к анализу запроса. Код: plsql 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.09.2017, 14:13 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39523902&tid=1885217]: |
0ms |
get settings: |
8ms |
get forum list: |
20ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
184ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
| others: | 221ms |
| total: | 501ms |

| 0 / 0 |
