|
Программирование >> Преобразование значений null
Для 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
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |