Sql where子句与connect by的交互,并创建查询以获取层次结构中的下一级
表: 资料 要求 汇总所有IT部门的工资: 类别工资 5,50 伊塞克,60岁 ITDBA,60岁 汇总公司各部门工资情况: 类别工资 它是170 市场,40 汇总所有ITDBA部门的工资: 类别工资 3,30 ITDBASQL,10 ITDbarc,20岁 您会注意到,我们正试图根据层次结构中的下一个级别进行汇总。如果任何emp已经是该级别的一部分,那么我们需要向员工展示 试问: 关注和疑问: 此查询是否在所有场景中都能正常工作。还有更好的方法吗?? where条件如何与connect by交互。例如,在子查询中,我们使用parent_dept='IT'进行筛选,但是,当通过某些emp启动连接时,可能会使用parent_dept='ITDBASQL',这也是它的一部分。我很难理解工作流程。 谢谢你的时间和帮助 还有更好的方法吗 这是一个等效的查询,每个表只需要一次表扫描。您需要确定您的查询或此查询对于您的数据/索引等是否更有效 Oracle 11g R2架构设置: 问题1: : 您可以单独运行查询以了解它们正在执行的操作:Sql where子句与connect by的交互,并创建查询以获取层次结构中的下一级,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,表: 资料 要求 汇总所有IT部门的工资: 类别工资 5,50 伊塞克,60岁 ITDBA,60岁 汇总公司各部门工资情况: 类别工资 它是170 市场,40 汇总所有ITDBA部门的工资: 类别工资 3,30 ITDBASQL,10 ITDbarc,20岁 您会注意到,我们正试图根据层次结构中的下一个级别进行汇总。如果任何emp已经是该级别的一部分,那么我们需要向员工展示 试问: 关注和疑问: 此查询是否在所有场景中都能正常工作。还有更好的方法吗?? where条件如何与connect by交
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获取层次结构分支根处的部门。“级别”和“行号”用于查找层次结构顶部的第一行。谢谢您的回答。因为我的主表中有所有适当的索引,所以我的查询执行得很快。我主要担心的是我不理解where条件&通过交互连接,特别是在这种情况下。请你解释一下好吗?如果我们试着向公司部门查询,它会重复金额。@pOrinG Updated
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
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
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;
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