Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
BD / Урок 12-Рекурсивный SQL.doc
Скачиваний:
56
Добавлен:
20.02.2016
Размер:
721.41 Кб
Скачать

Стандартное представление и манипулирование деревьями в sql

В SQL, любые связи явно описываются данными. Типичный способ представления деревьев состоит в том, чтобы поместить дуги между вершинами в таблицу. Т.е. один столбец — родительский узел, и другой столбец в той же самой строке — дочерний узел (пара представляет собой дугу в графе). Например, в нашей учебной базе данных таблица TEACHERпомимо первичного ключаTchPK, который уникально идентифицирует строки таблицы (то есть преподавателей) имеется внешний ключChief, который является ссылкой на руководителя данного преподавателя.

Чтобы по каждому руководителю получить имена их непосредственных подчиненных, следует использовать «самосоединяющийся» запрос типа:

SELECT mgr.Name AS "Руководитель", tch.Name AS "Подчиненный" FROM TEACHER tch, TEACHER mgr WHERE tch.Chief = mgr.TchPK ORDER BY mgr.Name;

Руководитель Подчиненный --------------- ------------ Заплатинский Козлитин Кузнецов Марченко Лебедь Недоводеев Радишевский Хоменко Радишевский Воробьев Радишевский Кузнецов Сидоров Радишевский Сидоров Заплатинский Сидоров Лебедь Сидоров Резник Хоменко Витковский

11 строк выбрано.

Этот запрос выдает только непосредственных подчиненных. Однако, подчиненные ваших подчиненных также «подвластны» вам, и так далее вниз по дереву. Чтобы вывести сведения по вершинам через уровень в дереве, необходимо написать более сложный запрос с троекратным объединением отношения, как это продемонстрировано ниже.

SELECT mgr.Name AS "Руководитель", tch.Name AS "Подчиненный 2 ур-ня" FROM TEACHER tch, TEACHER mid, TEACHER mgr WHERE tch.Chief = mid.TchPK AND mid.Chief = mgr.TchPK ORDER BY mgr.Name;

Руководитель Подчиненный 2 ур-ня --------------- ------------------- Радишевский Витковский Радишевский Марченко Сидоров Хоменко Сидоров Воробьев Сидоров Недоводеев Сидоров Кузнецов Сидоров Козлитин

7 строк выбрано.

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

Тем не менее, некоторые из элементов дерева могут эффективно отыскиваться. Так, например, можно легко находить вершины–листья, то есть такие, которые не имеют потомков. В нашем случае это преподаватели, не имеющие подчиненных. Вот как они находятся:

SELECT t1.Name AS "Вершины-листья" FROM TEACHER t1 WHERE NOT EXISTS (SELECT * FROM TEACHER t2 WHERE t2.Chief = t1.TchPK);

Вершины-листья ---------------- Витковский Воробьев Козлитин Марченко Резник Недоводеев Ахромеев Наумов Дараганов

9 строк выбрано.

А как найти корень дерева, то есть «самого высокого» начальника? Ответ на этот запрос зависит от того, какое значение столбца Chiefхранится для корня дерева, то есть для того сотрудника, у которого нет руководителя. Возможны два варианта: хранить в этом столбце значение столбцаTchPK(что, как мы увидим далее, не самый лучший вариант), то есть тем самым указать, что этот сотрудник является сам своим руководителем, и второй — хранить в этом поле значениеNULL. В первом случае для получения корня дерева следует записать:

SELECTNameFROMTEACHERWHERETchPK=Chief;

А во втором:

SELECT Name FROM TEACHER WHERE Chief IS NULL;

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