Отображение данных иерархии древовидной структуры Oracle в разных столбцах одной строки
У меня есть иерархическая таблица с именем Employee_Hierarchy в Oracle с именами столбцов entity_code, parent_entity_code, entity_name и entity_role без цикла. Имея более низкий самый ребенок в другой таблице с именем клиент связано с самым нижним дочерним элементом иерархической таблицы с entity_code. Я должен отобразить данные в иерархии одной строки, где имя столбца будет добавлено ролью.
образец Пример:
Древовидную Структуру:
Иерархической Таблице:
Нижняя таблица большинства детей:
ожидается Результат:
есть ли способ получить ожидаемый результат через oracle query? И ожидаемый результат зависит от ввода, что означает, что он не всегда будет начинаться с корневого элемента, он может начинаться с любого узла, например team-lead (Shail) до самого нижнего дочернего элемента.
(Примечание:Если отсутствует верхняя иерархия, то parent_code текущего узла будет parent_code его верхней иерархии и отсутствующим элемент иерархии будет пустым в ожидаемом результате.)
спасибо заранее.
4 ответов
select h.Manager_entity_code
,h.Manager_entity_name
,h.Team_Lead_entity_code
,h.Team_Lead_entity_name
,h.Developer_entity_code
,h.Developer_entity_name
,c.client_name
from (select trim (both ',' from sys_connect_by_path (case when entity_role = 'Manager' then entity_code end,',')) as Manager_entity_code
,trim (both ',' from sys_connect_by_path (case when entity_role = 'Manager' then entity_name end,',')) as Manager_entity_name
,trim (both ',' from sys_connect_by_path (case when entity_role = 'Team-Lead' then entity_code end,',')) as Team_Lead_entity_code
,trim (both ',' from sys_connect_by_path (case when entity_role = 'Team-Lead' then entity_name end,',')) as Team_Lead_entity_name
,trim (both ',' from sys_connect_by_path (case when entity_role = 'Developer' then entity_code end,',')) as Developer_entity_code
,trim (both ',' from sys_connect_by_path (case when entity_role = 'Developer' then entity_name end,',')) as Developer_entity_name
from hierarchical_table
where connect_by_isleaf = 1
connect by parent_entity_code = prior entity_code
start with entity_code = 100
) h
join client_table c
on c.entity_code =
h.Developer_entity_code
order by h.Manager_entity_code
,h.Team_Lead_entity_code
,h.Developer_entity_code
;
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| MANAGER_ENTITY_CODE | MANAGER_ENTITY_NAME | TEAM_LEAD_ENTITY_CODE | TEAM_LEAD_ENTITY_NAME | DEVELOPER_ENTITY_CODE | DEVELOPER_ENTITY_NAME | CLIENT_NAME |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| 100 | Mack | 200 | Shail | 500 | Neha | Tata |
| 100 | Mack | 300 | Jack | 600 | Rocky | Rel |
| 100 | Mack | 300 | Jack | 600 | Rocky | Voda |
| 100 | Mack | 300 | Jack | 600 | Rocky | Airtel |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
на start with entity_code = 300
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| MANAGER_ENTITY_CODE | MANAGER_ENTITY_NAME | TEAM_LEAD_ENTITY_CODE | TEAM_LEAD_ENTITY_NAME | DEVELOPER_ENTITY_CODE | DEVELOPER_ENTITY_NAME | CLIENT_NAME |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| (null) | (null) | 300 | Jack | 600 | Rocky | Airtel |
| (null) | (null) | 300 | Jack | 600 | Rocky | Voda |
| (null) | (null) | 300 | Jack | 600 | Rocky | Rel |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
в результатах запроса вы ожидаете, что определенные роли будут иметь определенную позицию в иерархии. Менеджер первого уровня руководители второго, разработчики третьей. Таким образом, вы можете относиться к своей иерархической таблице, как если бы это было не так. Это делает запрос очень четкий:
with manager as (select * from employee_hierarchy where entity_role = 'Manager')
, teamleader as (select * from employee_hierarchy where entity_role = 'Team-Lead')
, developer as (select * from employee_hierarchy where entity_role = 'Developer')
select
m.entity_code as manager_entity_code,
m.entity_name as manager_entity_name,
t.entity_code as team_lead_entity_code,
t.entity_name as team_lead__entity_name,
d.entity_code as developer_entity_code,
d.entity_name as developer_entity_name,
c.client_name
from manager m
join teamleader t on t.parent_entity_code = m.entity_code
join developer d on d.parent_entity_code = t.entity_code
left join client_table c on c.entity_code = d.entity_code;
и если вы хотите ограничить результаты отделом лидера команды Шейла, просто добавьте соответствующий WHERE
статья:
where t.entity_name = 'Shail'
вот один из способов сделать это, используя присоединяется. Альтернативой является объединение двух таблиц и выполнение иерархического запроса - но это действительно одно и то же (иерархический запрос-это не что иное, как рекурсивное самосоединение).
with
hierarchical_table ( entity_code, entity_name, entity_role, parent_entity_code ) as (
select 100, 'Mack' , 'Manager', cast (null as number) from dual union all
select 200, 'Shail', 'Team-Lead', 100 from dual union all
select 300, 'Jack' , 'Team-Lead', 100 from dual union all
select 400, 'Teju' , 'Developer', 200 from dual union all
select 500, 'Neha' , 'Developer', 200 from dual union all
select 600, 'Rocky', 'Developer', 300 from dual
),
client_table ( entity_code, client_name, address ) as (
select 600, 'Voda' , 'Pune' from dual union all
select 600, 'Rel' , 'Mumbai' from dual union all
select 600, 'Airtel', 'Pune' from dual union all
select 500, 'Tata' , 'Mumbai' from dual
)
-- end of test data (not part of the solution)
-- SQL query begins BELOW THIS LINE; use your actual table names
select h1.entity_code as manager_code, h1.entity_name as manager_name,
h2.entity_code as teamlead_code, h2.entity_name as teamlead_name,
h3.entity_code as developer_code, h3.entity_name as developer_name,
c.client_name
from hierarchical_table h1 left join hierarchical_table h2
on h2.parent_entity_code = h1.entity_code
left join hierarchical_table h3
on h3.parent_entity_code = h2.entity_code
left join client_table c
on c.entity_code = h3.entity_code
where h1.parent_entity_code is null
order by manager_code, teamlead_code, developer_code, client_name
;
выход:
MANAGER_CODE MANAGER_NAME TEAMLEAD_CODE TEAMLEAD_NAME DEVELOPER_CODE DEVELOPER_NAME CLIENT
------------ ------------ ------------- ------------- -------------- -------------- ------
100 Mack 200 Shail 400 Teju
100 Mack 200 Shail 500 Neha Tata
100 Mack 300 Jack 600 Rocky Airtel
100 Mack 300 Jack 600 Rocky Rel
100 Mack 300 Jack 600 Rocky Voda
5 rows selected.
select regexp_substr (h.entity,'Manager~([^~]*)~' ,1,1,'',1) as Manager_entity_code
,regexp_substr (h.entity,'Manager~([^~]*)~([^,]*)' ,1,1,'',2) as Manager_entity_name
,regexp_substr (h.entity,'Team-Lead~([^~]*)~' ,1,1,'',1) as Team_Lead_entity_code
,regexp_substr (h.entity,'Team-Lead~([^~]*)~([^,]*)',1,1,'',2) as Team_Lead_entity_name
,regexp_substr (h.entity,'Developer~([^~]*)~' ,1,1,'',1) as Developer_entity_code
,regexp_substr (h.entity,'Developer~([^~]*)~([^,]*)',1,1,'',2) as Developer_entity_name
,c.client_name
from (select sys_connect_by_path (entity_role || '~' || entity_code || '~' || entity_name,',') as entity
,entity_code
from hierarchical_table
where connect_by_isleaf = 1
connect by parent_entity_code = prior entity_code
start with entity_code = 200
) h
join client_table c
on c.entity_code =
h.entity_code
order by Manager_entity_code
,Team_Lead_entity_code
,Developer_entity_code
;
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| MANAGER_ENTITY_CODE | MANAGER_ENTITY_NAME | TEAM_LEAD_ENTITY_CODE | TEAM_LEAD_ENTITY_NAME | DEVELOPER_ENTITY_CODE | DEVELOPER_ENTITY_NAME | CLIENT_NAME |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| 100 | Mack | 200 | Shail | 500 | Neha | Tata |
| 100 | Mack | 300 | Jack | 600 | Rocky | Rel |
| 100 | Mack | 300 | Jack | 600 | Rocky | Voda |
| 100 | Mack | 300 | Jack | 600 | Rocky | Airtel |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
на start with entity_code = 600
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| MANAGER_ENTITY_CODE | MANAGER_ENTITY_NAME | TEAM_LEAD_ENTITY_CODE | TEAM_LEAD_ENTITY_NAME | DEVELOPER_ENTITY_CODE | DEVELOPER_ENTITY_NAME | CLIENT_NAME |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+
| (null) | (null) | (null) | (null) | 600 | Rocky | Airtel |
| (null) | (null) | (null) | (null) | 600 | Rocky | Voda |
| (null) | (null) | (null) | (null) | 600 | Rocky | Rel |
+---------------------+---------------------+-----------------------+-----------------------+-----------------------+-----------------------+-------------+