如下:
-- 公司/部门表
drop table sys_company_dept;
create table sys_company_dept
(
dept_id varchar2(20),
dept_name varchar2(50),
parent_id varchar2(20)
);
alter table SYS_COMPANY_DEPT
add constraint key_dept_id primary key (DEPT_ID);
comment on table SYS_COMPANY_DEPT
is '公司和部门表';
comment on column SYS_COMPANY_DEPT.dept_id
is '公司(部门)id';
comment on column SYS_COMPANY_DEPT.dept_name
is '公司(部门)名';
comment on column SYS_COMPANY_DEPT.parent_id
is '父id';
-- 用户表
drop table sys_user;
create table sys_user
(
user_id varchar2(20),
user_name varchar2(50),
dept_id varchar2(20),
salary number(5)
);
alter table sys_user
add constraint key_user_id primary key (user_id);
comment on table sys_user
is '用户表';
comment on column sys_user.user_id
is '用户id';
comment on column sys_user.user_name
is '用户名';
comment on column sys_user.dept_id
is '部门id';
comment on column sys_user.salary
is '薪水';
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('A000', 'XXX科技有限公司', null);
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('B001', '郑州分公司', 'A000');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('B002', '厦门分公司', 'A000');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('B003', '武汉分公司', 'A000');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('B004', '成都分公司', 'A000');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('B005', '南京分公司', 'A000');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('C001', '郑州-科技部', 'B001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('C002', '郑州-业务部', 'B001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('C003', '郑州-人事部', 'B001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('C004', '郑州-财务部', 'B001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('D001', '郑州-科技部-开发部', 'C001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('D002', '郑州-科技部-测试部', 'C001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('D003', '郑州-科技部-需求分析部', 'C001');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('C005', '厦门-科技部', 'B002');
insert into sys_company_dept (DEPT_ID, DEPT_NAME, PARENT_ID)
values ('C006', '武汉-财务部', 'B003');
-- -----------------------------------------
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1001', '大佬', 'A000', 0);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1002', '二佬', 'A000', 80000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1003', '郑董事', 'B001', 70000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1004', '郑科技', 'C001', 60000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1005', '郑开发1', 'D001', 50000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1006', '郑开发2', 'D001', 51000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1007', '郑开发3', 'D001', 52000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1008', '郑测试1', 'D002', 40000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1009', '郑测试2', 'D002', 40000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1010', '郑需求', 'D003', 45000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1011', '郑业务', 'C002', 30000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1012', '郑人事', 'C003', 30000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1013', '郑财务', 'C004', 30000);
insert into sys_user (USER_ID, USER_NAME, DEPT_ID, SALARY)
values ('1014', '厦公司', 'B002', 60000);
如下:



-- 不包括起始父节点
select * from sys_company_dept
start with parent_id='B001' connect by prior dept_id=parent_id;

-- 包括起始父节点
select * from sys_company_dept
start with dept_id='B001' connect by prior dept_id=parent_id;
select * from sys_company_dept connect by prior dept_id=parent_id
start with dept_id='B001' ;

select * from sys_company_dept
start with dept_id='D003'
connect by prior parent_id=dept_id;
connect by prior 后面跟的是 dept_id 还是 parent_id,这是二者区别的关键
select * from sys_company_dept
where 1=1 and parent_id='A000'
start with dept_id='D003'
connect by prior parent_id=dept_id;

select (rpad(' ', 2*(level-1), '-|' ) || dept_name) dept_name,level,dept_id,parent_id
FROM sys_company_dept
start with parent_id is null
connect by prior dept_id = parent_id;

select (rpad(' ', 2*(level-1), '-|' ) || dept_name) dept_name,
connect_by_root dept_name as root_dept_name,
connect_by_isleaf, level ,
sys_connect_by_path(dept_name, '/')
FROM sys_company_dept
start with parent_id is null
connect by prior dept_id = parent_id;
CONNECT_BY_ROOT 返回当前节点的最顶端节点CONNECT_BY_ISLEAF 判断是否为叶子节点(0-否,1-是),如果这个节点下面有子节点,则不是叶子节点 ,否则为叶子节点LEVEL 伪列表示节点深度SYS_CONNECT_BY_PATH 函数显示详细层次路径,并用“/”分隔CONNECT_BY_ROOT 可以得到每个分支的根节点信息,如下:
select t.dept_id,t.dept_name,connect_by_root(t.dept_id) root_id,rownum row_num
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id;


with temp1 as(
select t.dept_id,t.dept_name,t.type,connect_by_root(t.dept_id) root_id
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
)
select t1.dept_id,t1.dept_name,t1.root_id as company_id,t2.dept_name as company_name,
(case t1.type when '1' then '公司' else '部门' end)type
from temp1 t1
left join sys_company_dept t2 on t1.root_id = t2.dept_id
where t2.type='1' and t2.dept_id!='A000';


-- 统计
select t2.root_id,root_name,count(0) from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
)t2 group by t2.root_id,root_name;
再上面语法都了解的基础上,我们再写这个统计就很简单了,如下:

检查一下统计的是否正确


sql语句-两种写法
第①种写法:
select root_id,root_name,sum(sum_user) sum_user from (
select user_id,temp1.dept_id,(case when user_id is null then 0 else 1 end) sum_user,
root_id,root_name
from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)temp2
group by root_id,root_name;
第②种写法:
with temp2 as(
select user_id,temp1.dept_id,(case when user_id is null then 0 else 1 end) sum_user,root_id,root_name
from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)
select root_id,root_name,sum(sum_user) sum_user from temp2 group by root_id,root_name;

select root_id,root_name,sum(sum_user) sum_user from (
select user_id,temp1.dept_id,(case when user_id is null then 0 else 1 end) sum_user,
root_id,root_name
from (
select t0.dept_id,t0.dept_name,
connect_by_root(t0.dept_id) root_id,connect_by_root(t0.dept_name) root_name
from (
select t.dept_id,t.dept_name,t.parent_id
from sys_company_dept t
start with t.dept_id ='B001' -- D001 B001
connect by prior t.dept_id = t.parent_id)t0
start with t0.dept_id in(select dept_id from sys_company_dept)
connect by prior t0.dept_id = t0.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)temp2
group by root_id,root_name;


with temp2 as(
select temp1.dept_id,nvl(u.salary, 0) sum_salary,root_id,root_name
from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)
select root_id,root_name,sum(sum_salary) sum_salary from temp2 group by root_id,root_name;
-- 查子节点
select * from sys_company_dept
start with parent_id='A000'
connect by prior dept_id=parent_id;
select * from sys_company_dept
start with dept_id='A000'
connect by prior dept_id=parent_id;
-- 根据部门 id 查所有父节点
select * from sys_company_dept
start with dept_id='D003'
connect by prior parent_id=dept_id;
-- 查他爹的公司
select * from sys_company_dept
where 1=1 and parent_id='A000'
start with dept_id='D003'
connect by prior parent_id=dept_id;
-------树形结构查询 1
select (rpad(' ', 2*(level-1), '-|' ) || dept_name) dept_name,
level,dept_id,parent_id
FROM sys_company_dept
start with parent_id is null
connect by prior dept_id = parent_id;
-------树形结构查询 2
select (rpad(' ', 2*(level-1), '-|' ) || dept_name) dept_name,
connect_by_root dept_name as root_dept_name,
connect_by_isleaf, level ,
sys_connect_by_path(dept_name, '/')
FROM sys_company_dept
start with parent_id is null
connect by prior dept_id = parent_id;
-- ----------------------
select t.dept_id,t.dept_name,connect_by_root(t.dept_id) root_id,rownum row_num
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id;
-- 统计 子部门个数
select t2.root_id,root_name,count(0) from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
)t2 group by t2.root_id,root_name;
-- 统计 各公司的人员人数
-- 统计人数 1法
select root_id,root_name,sum(sum_user) sum_user from (
select user_id,temp1.dept_id,(case when user_id is null then 0 else 1 end) sum_user,
root_id,root_name
from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)temp2
group by root_id,root_name;
-----统计人数 2法
with temp2 as(
select user_id,temp1.dept_id,(case when user_id is null then 0 else 1 end) sum_user,root_id,root_name
from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)
select root_id,root_name,sum(sum_user) sum_user from temp2 group by root_id,root_name;
-- 统计 各公司的人员薪水总和
with temp2 as(
select temp1.dept_id,nvl(u.salary, 0) sum_salary,root_id,root_name
from (
select t.dept_id,t.dept_name,
connect_by_root(t.dept_id) root_id,connect_by_root(t.dept_name) root_name
from sys_company_dept t
start with t.dept_id in(select dept_id from sys_company_dept)
connect by prior t.dept_id = t.parent_id
) temp1 left join sys_user u on temp1.dept_id = u.dept_ID
)
select root_id,root_name,sum(sum_salary) sum_salary from temp2 group by root_id,root_name;