[英]Interaction of where clause with connect by And Creating query to fetch next level in a hierarchy
表:
create table temp_hierarchy_define (dept varchar2(25), parent_dept varchar2(25))
create table temp_employee (empid number(1), empname varchar2(50), dept varchar2(25), salary number(10))
數據
Select 'COMPANY' dept , 'COMPANY' parent_dept From Dual Union All
Select 'IT' , 'COMPANY' From Dual Union All
Select 'MARKET' , 'COMPANY' From Dual Union All
Select 'ITSEC' , 'IT' From Dual Union All
Select 'ITDBA' , 'IT' From Dual Union All
Select 'ITDBAORC' , 'ITDBA' From Dual Union All
Select 'ITDBASQL' , 'ITDBA' From Dual
select 1 empid, 'Rohan-ITDBASQL' empname ,'ITDBASQL' dept ,10 salary from dual union all
select 2, 'Raj-ITDBAORC' ,'ITDBAORC' ,20 from dual union all
select 3, 'Roy-ITDBA' ,'ITDBA' ,30 from dual union all
select 4, 'Ray-MARKET' ,'MARKET' ,40 from dual union all
select 5, 'Roopal-IT' ,'IT' ,50 from dual union all
select 6, 'Ramesh-ITSEC' ,'ITSEC' ,60 from dual
需求
匯總所有IT部門的薪水:
類別工資
5,50
ITSEC,60
ITDBA,60
匯總所有公司部門的工資:
類別工資
IT,170
市場的40
匯總所有ITDBA部門的薪水:
類別工資
3,30
ITDBASQL,10
ITDBAORC,20
您會注意到,我們正在嘗試根據層次結構中的下一個層次進行總結。 如果任何一個emp已經屬於該級別,那么我們需要向員工展示。
試用查詢:
Select Category,sum(salary) from (
Select
NVL((Select dept.dept from temp_hierarchy_define dept
Where dept.parent_dept = 'IT'
And dept.dept != 'IT'
Start With dept.dept = emp.dept
Connect by NOCYCLE dept.dept = Prior dept.parent_dept
and prior dept.dept is not null),emp.empid) category,
emp.*
From temp_employee emp
Where emp.DEPT in
(Select dept.dept from temp_hierarchy_define dept
Start With dept.dept = 'IT'
connect by nocycle prior dept.dept = dept.parent_dept) ) Group by Category
問題和疑問:
parent_dept = 'IT'
進行過濾,但是在通過某些emp開始連接時,可能具有parent_dept = 'ITDBASQL'
,它也是IT的一部分。 我很難理解工作流程。 感謝您的時間和協助。
還是有更好的方法呢?
這是等效查詢,每個表只需要掃描一次表。 您將需要確定您的查詢或該查詢對於您的數據/索引/等是否更有效。
Oracle 11g R2架構設置 :
create table temp_hierarchy_define (
dept varchar2(25), parent_dept varchar2(25));
create table temp_employee (
empid number(1), empname varchar2(50), dept varchar2(25), salary number(10));
INSERT INTO temp_hierarchy_define( dept, parent_dept )
Select 'COMPANY' , 'COMPANY' From Dual Union All
Select 'IT' , 'COMPANY' From Dual Union All
Select 'MARKET' , 'COMPANY' From Dual Union All
Select 'ITSEC' , 'IT' From Dual Union All
Select 'ITDBA' , 'IT' From Dual Union All
Select 'ITDBAORC' , 'ITDBA' From Dual Union All
Select 'ITDBASQL' , 'ITDBA' From Dual;
INSERT INTO temp_employee( empid, empname, dept, salary )
select 1, 'Rohan-ITDBASQL' ,'ITDBASQL' ,10 from dual union all
select 2, 'Raj-ITDBAORC' ,'ITDBAORC' ,20 from dual union all
select 3, 'Roy-ITDBA' ,'ITDBA' ,30 from dual union all
select 4, 'Ray-MARKET' ,'MARKET' ,40 from dual union all
select 5, 'Roopal-IT' ,'IT' ,50 from dual union all
select 6, 'Ramesh-ITSEC' ,'ITSEC' ,60 from dual;
查詢1 :
SELECT dept,
SUM( salary )
FROM (
SELECT CASE
WHEN lvl = 1 AND h.parent_dept = e.dept
THEN CAST( e.empid AS VARCHAR2(25) )
ELSE root_dept
END AS dept,
e.empid,
e.salary
FROM ( SELECT CONNECT_BY_ROOT( dept ) AS root_dept,
h.*,
LEVEL AS lvl,
ROW_NUMBER() OVER ( PARTITION BY parent_dept ORDER BY ROWNUM ) AS rn
FROM temp_hierarchy_define h
WHERE parent_dept != dept
START WITH h.parent_dept = 'IT'
CONNECT BY NOCYCLE PRIOR h.dept = h.parent_dept
) h
LEFT OUTER JOIN
temp_employee e
ON ( h.dept = e.dept
OR ( h.parent_dept = e.dept AND h.lvl = 1 AND h.rn = 1)
)
)
GROUP BY dept
結果 :
| DEPT | SUM(SALARY) |
|-------|-------------|
| ITDBA | 60 |
| 5 | 50 |
| ITSEC | 60 |
您可以單獨運行查詢以查明它們在做什么:
SELECT CONNECT_BY_ROOT( dept ) AS root_dept,
h.*,
LEVEL AS lvl,
ROW_NUMBER() OVER ( PARTITION BY parent_dept ORDER BY ROWNUM ) AS rn
FROM temp_hierarchy_define h
WHERE parent_dept != dept
START WITH h.parent_dept = 'IT'
CONNECT BY NOCYCLE PRIOR h.dept = h.parent_dept
僅列出層次結構中的所有行,並使用CONNECT_BY_ROOT
將部門設置為層次結構分支的根。 LEVEL
和ROW_NUMBER()
用於查找層次結構頂部的第一行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.