- •Урок 12. РекурсивныйSql
- •Древовидные структуры
- •Стандартное представление и манипулирование деревьями в sql
- •Рекурсивные запросы в Oracle
- •Фраза startwith
- •Фраза connectby
- •Использование псевдостолбца level
- •Задание условия
- •Условие на глубину иерархической структуры
- •Упорядочение строк с помощью фразы order by
- •Подзапрос в startwith
- •Рекурсивные запросы в стандарте sql
- •Определение повторяющихся подзапросов
- •Рекурсивное выполнение запросов
- •Примеры рекурсивных запросов: рейсовые полеты
- •Рекурсия с накоплением
- •Рекурсия и соединение таблиц
- •Отрицание и группирование в рекурсии
- •Примеры рекурсивных запросов: комплектация изделий
- •Вычисление промежуточных количественных характеристик
- •Итоговые количественные вычисления
- •Игнорирование фиктивных изделий
- •В каких агрегатах используется деталь?
- •Parts explosion excluding base parts (Testing For Leaf Nodes In a Parts Explosion)
- •Характеристики поиска
- •Фиксация наличия циклов
- •Направление поиска
- •Более сложная структура рекурсивного запроса
- •Рекурсивные представления
- •Различные виды рекурсии
- •Прямая и взаимная рекурсия
- •Линейная и нелинейная рекурсия
- •Подведение итогов
- •Самостоятельная работа
Упорядочение строк с помощью фразы order by
Как мы уже отмечали, порядок обхода строк иерархического дерева сверху–вниз, слева–направо. Именно в этом порядке строки и выводятся. Если необходимо изменить порядок вывода, то следует прибегнуть к фразе ORDER BY. Вот как выглядит предыдущий пример, дополненный этой фразой.
SELECTLPAD(' ',2*(LEVEL-1)) ||NameAS"Фамилия",TchPKAS"Номер преп.",ChiefAS"Номер руков.",PostAS"Должность преп."FROM TEACHER START WITH UPPER(Name) = 'РАДИШЕВСКИЙ' CONNECT BY PRIOR TchPK = Chief ORDER BY Name;
Фамилия Номер преп. Номер руков. Должность преп. ----------------- ----------- ------------ --------------- Витковский 1 2 ассистент Воробьев 3 4 ассистент Кузнецов 5 4 преподаватель Марченко 9 5 ассистент Радишевский 4 16 доцент Хоменко 2 4 преподаватель
6 строк выбрано.
Результат упорядочен по фамилиям, но не совсем понятно кто кому подчинен. Чтобы решить эту проблему существует разновидность упорядочения, которая выражается фразой ORDER SIBLINGS BY. Она действует только в иерархических запросах (то есть имеющих фразуCONNECT BY) и означает следующее: иерархическая упорядоченность сохраняется за исключением того, что производится сортировка вершин, непосредственно принадлежащих одной родительской вершины. Приведем пример такого упорядочения.
SELECTLPAD(' ',2*(LEVEL-1)) ||NameAS"Фамилия",TchPKAS"Номер преп.",ChiefAS"Номер руков.",PostAS"Должность преп."FROM TEACHER START WITH UPPER(Name) = 'РАДИШЕВСКИЙ' CONNECT BY PRIOR TchPK = Chief ORDER SIBLINGS BY Name;
Фамилия Номер преп. Номер руков. Должность преп. ----------------- ----------- ------------ --------------- Радишевский 4 16 доцент Воробьев 3 4 ассистент Кузнецов 5 4 преподаватель Марченко 9 5 ассистент Хоменко 2 4 преподаватель Витковский 1 2 ассистент
6 строк выбрано.
Как видим, иерархическая вложенность сохранена и все преподаватели, подчиненные Радишевскому, отсортированы. Во фразе ORDER SIBLINGS BYпараметры точно такие же, как и вORDER BY.
Подзапрос в startwith
Фраза START WITHможет содержать подзапрос, который выступает одним из операндов оператора сравнения. Например, в следующем запросе отбор в иерархической структуре начинается с руководителя преподавателя Недоводеева.
SELECTLPAD(' ',2*(LEVEL-1)) ||NameAS"Фамилия",TchPKAS"Номер преп.",ChiefAS"Номер руков.",PostAS"Должность преп."FROM TEACHER START WITH TchPK = (SELECT Chief FROM TEACHER WHERE UPPER(name)= 'НЕДОВОДЕЕВ') CONNECT BY PRIOR TchPK = Chief;
Фамилия Номер преп. Номер руков. Должность преп. ----------------- ----------- ------------ --------------- Лебедь 7 16 доцент Недоводеев 11 7 преподаватель
2 строк выбрано.