Программирование >>  Преобразование значений null 

1 ... 166 167 168 [ 169 ] 170 171 172 ... 219



Для Oracle 8i Database и более ранних версий можно использовать решение для PostgreSQL. Или, поскольку CONNECT BY доступен в более старых версиях Oracle, форматирование можно выполнять с помощью LEVEL и RPAD/LPAD (хотя, чтобы воспроизвести результат, обеспечиваемый SYS CONNECT BY PATH, придется немного потрудиться).

PostgreSQL и MySQL

За исключением конкатенации строк в операторах SELECT, решения для PostgreSQL и MySQL одинаковые. Первый шаг - определить максимальное число узлов для каждой ветки. Это необходимо сделать самостоятельно до создания запроса. Если проанализировать данные таблицы EMP, можно увидеть, что служащие ADAM и SMITH являются концевыми узлами с самым глубоким уровнем вложенности (загляните в раздел обсуждения решения для Oracle, где найдете правильно отформатированное дерево иерархии EMP). Рассмотрим служащего ADAMS. Он является подчиненным SCOTT, который, в свою очередь, подчиняется JONES, который подчиняется KING. Таким образом, глубина равна 4. Чтобы представить иерархию с четырехкратной глубиной вложенности, необходимо выполнить рефлексивное объединение четырех экземпляров таблицы EMP и написать запрос с оператором UNION, состоящим из четырех частей. Результаты четырехкратного рефлексивного объединения (нижняя часть последнего UNION, если рассматривать сверху вниз) показаны ниже (с использованием синтаксиса PostgreSQL; пользователи MySQL просто заменяют оператор вызовом функции CONCAT):

select rtrim(a.ename - b.ename -

c.ename - d.ename, - ) as max depth 4

from emp a

join

emp b on (a.empno=b.mgr)

join

emp c on (b.empno=c.mgr) left join

emp d on (c.empno=d.mgr) where a.ename = KING

MAX DEPTH 4

KING - JONES - FORD - SMITH

KING - JONES - SCOTT - ADAMS

KING - BLAKE - TURNER

KING - BLAKE - ALLEN

KING - BLAKE - WARD

KING - CLARK - MILLER

KING - BLAKE - MARTIN

KING - BLAKE - JAMES



Фильтр по A.ENAME гарантирует, что корневой строкой является KING и никакая другая строка. Если взглянуть на приведенное выше результирующее множество и сравнить его с конечным результатом, можно заметить отсутствие нескольких строк, представляющих третий уровень иерархии: KING-JONES-FORD и KING-JONES-SCOTT. Чтобы эти строки вошли в результирующее множество, необходимо написать еще один запрос, подобный приведенному выше, но в котором было бы на единицу меньше объединений (рефлексивные объединения всего трех экземпляров таблицы EMP, а не четырех). Результирующее множество этого запроса показано ниже:

select rtrim(a.ename - b.ename

- c.ename, - ) as max depth 3

from emp a join

emp b on (a.empno=b.mgr) left join

emp c on (b.empno=c.mgr) where a.ename = KING

MAX DEPTH 3

KING - BLAKE - ALLEN

KING - BLAKE - WARD

KING - BLAKE - MARTIN

KING - JONES - SCOTT

KING - BLAKE - TURNER

KING - BLAKE - JAMES

KING - JONES - FORD

KING - CLARK - MILLER

Как в предыдущем запросе, здесь фильтр A.ENAME гарантирует, что корневым узлом является KING. Можно заметить, что строки, возвращаемые данным запросом, частично повторяют строки, возвращаемые предыдущим четырехкратным объединением EMP. Чтобы избавиться от лишних строк, просто объединим (с помощью оператора UNION) два запроса:

select rtrim(a.ename - b.ename

- c.ename, - ) as partial tree

from emp a join

emp b on (a.empno=b.mgr)

left join

emp c on (b.empno=c.mgr) where a.ename = KING union

select rtrim(a.ename - b.ename - c.ename - d.ename, - )

from emp a join

emp b on (a.empno=b.mgr)



join

emp c on (b.empno=c.mgr) left join

emp d on (c.empno=d.mgr) where a.ename = KING

PARTIAL TREE

KING - BLAKE - ALLEN

KING - BLAKE - JAMES

KING - BLAKE - MARTIN

KING - BLAKE - TURNER

KING - BLAKE - WARD

KING - CLARK - MILLER

KING - JONES - FORD

KING - JONES - FORD - SMITH

KING - JONES - SCOTT

KING - JONES - SCOTT - ADAMS

Сейчас дерево почти готово. Следующий шаг - выбрать строки, представляющие второй уровень иерархии, где KING - корневой узел (т. е. служащих, находящихся в прямом подчинении у KING). Запрос, возвращающий эти строки, показан ниже:

select a.ename - b.ename as max depth 2 from emp a

join

emp b on (a.empno=b.mgr) where a.mgr is null

MAX DEPTH 2

KING - JONES KING - BLAKE KING - CLARK

Следующий шаг - объединить (с помощью оператора UNION) приведенный выше запрос с объединением PARTIAL TREE:

select a.ename - b.ename as partial tree from emp a

join

emp b on (a.empno=b.mgr) where a.mgr is null union

select rtrim(a.ename - b.ename

- c.ename, - )

from emp a

join

emp b on (a.empno=b.mgr) left join

emp c on (b.empno=c.mgr) where a.ename = KING union



1 ... 166 167 168 [ 169 ] 170 171 172 ... 219

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика