LeetCode_sql刷题(3482.分析组织层级)

题目描述:3482. 分析组织层级 - 力扣(LeetCode)

表:Employees

+----------------+---------+
| Column Name    | Type    | 
+----------------+---------+
| employee_id    | int     |
| employee_name  | varchar |
| manager_id     | int     |
| salary         | int     |
| department     | varchar |
+----------------+----------+
employee_id 是这张表的唯一主键。
每一行包含关于一名员工的信息,包括他们的 ID,姓名,他们经理的 ID,薪水和部门。
顶级经理(CEO)的 manager_id 是空的。

编写一个解决方案来分析组织层级并回答下列问题:

  1. 层级:对于每名员工,确定他们在组织中的层级(CEO 层级为 1,CEO 的直接下属员工层级为 2,以此类推)。
  2. 团队大小:对于每个是经理的员工,计算他们手下的(直接或间接下属)总员工数。
  3. 薪资预算:对于每个经理,计算他们控制的总薪资预算(所有手下员工的工资总和,包括间接下属,加上自己的工资)。

返回结果表以 层级 升序 排序,然后以预算 降序 排序,最后以 employee_name 升序 排序。

结果格式如下所示。

示例:

输入:

Employees 表:

+-------------+---------------+------------+--------+-------------+
| employee_id | employee_name | manager_id | salary | department  |
+-------------+---------------+------------+--------+-------------+
| 1           | Alice         | null       | 12000  | Executive   |
| 2           | Bob           | 1          | 10000  | Sales       |
| 3           | Charlie       | 1          | 10000  | Engineering |
| 4           | David         | 2          | 7500   | Sales       |
| 5           | Eva           | 2          | 7500   | Sales       |
| 6           | Frank         | 3          | 9000   | Engineering |
| 7           | Grace         | 3          | 8500   | Engineering |
| 8           | Hank          | 4          | 6000   | Sales       |
| 9           | Ivy           | 6          | 7000   | Engineering |
| 10          | Judy          | 6          | 7000   | Engineering |
+-------------+---------------+------------+--------+-------------+

输出:

+-------------+---------------+-------+-----------+--------+
| employee_id | employee_name | level | team_size | budget |
+-------------+---------------+-------+-----------+--------+
| 1           | Alice         | 1     | 9         | 84500  |
| 3           | Charlie       | 2     | 4         | 41500  |
| 2           | Bob           | 2     | 3         | 31000  |
| 6           | Frank         | 3     | 2         | 23000  |
| 4           | David         | 3     | 1         | 13500  |
| 7           | Grace         | 3     | 0         | 8500   |
| 5           | Eva           | 3     | 0         | 7500   |
| 9           | Ivy           | 4     | 0         | 7000   |
| 10          | Judy          | 4     | 0         | 7000   |
| 8           | Hank          | 4     | 0         | 6000   |
+-------------+---------------+-------+-----------+--------+

解释:

  • 组织结构:
    • Alice(ID:1)是 CEO(层级 1)没有经理。
    • Bob(ID:2)和 Charlie(ID:3)是 Alice 的直接下属(层级 2)
    • David(ID:4),Eva(ID:5)从属于 Bob,而 Frank(ID:6)和 Grace(ID:7)从属于 Charlie(层级 3)
    • Hank(ID:8)从属于 David,而 Ivy(ID:9)和 Judy(ID:10)从属于 Frank(层级 4)
  • 层级计算:
    • CEO(Alice)层级为 1
    • 每个后续的管理层级都会使层级数加 1
  • 团队大小计算:
    • Alice 手下有 9 个员工(除她以外的整个公司)
    • Bob 手下有 3 个员工(David,Eva 和 Hank)
    • Charlie 手下有 4 个员工(Frank,Grace,Ivy 和 Judy)
    • David 手下有 1 个员工(Hank)
    • Frank 手下有 2 个员工(Ivy 和 Judy)
    • Eva,Grace,Hank,Ivy 和 Judy 没有直接下属(team_size = 0)
  • 预算计算:
    • Alice 的预算:她的工资(12000)+ 所有员工的工资(72500)= 84500
    • Charlie 的预算:他的工资(10000)+ Frank 的预算(23000)+ Grace 的工资(8500)= 41500
    • Bob 的预算:他的工资 (10000) + David 的预算(13500)+ Eva 的工资(7500)= 31000
    • Frank 的预算:他的工资 (9000) + Ivy 的工资(7000)+ Judy 的工资(7000)= 23000
    • David 的预算:他的工资 (7500) + Hank 的工资(6000)= 13500
    • 没有直接下属的员工的预算等于他们自己的工资。

注意:

  • 结果先以层级升序排序
  • 在同一层级内,员工按预算降序排序,然后按姓名升序排序
数据准备
CREATE TABLE if not exists Employees (employee_id INT,employee_name VARCHAR(100),manager_id INT,salary INT,department VARCHAR(50)
)
Truncate table Employees
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('1', 'Alice', NULL, '12000', 'Executive')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('2', 'Bob', '1', '10000', 'Sales')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('3', 'Charlie', '1', '10000', 'Engineering')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('4', 'David', '2', '7500', 'Sales')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('5', 'Eva', '2', '7500', 'Sales')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('6', 'Frank', '3', '9000', 'Engineering')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('7', 'Grace', '3', '8500', 'Engineering')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('8', 'Hank', '4', '6000', 'Sales')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('9', 'Ivy', '6', '7000', 'Engineering')
insert into Employees (employee_id, employee_name, manager_id, salary, department) values ('10', 'Judy', '6', '7000', 'Engineering')

分析

①使用recursive进行递归查询 通过引用 CTE 自身不断生成新的结果集,直到满足终止条件主表 employee_id 和 子表manager_id 连接条件 直到employee_id遍历完  通过子表employee_id 记录路径,level记录层级 

with recursive t1 as (select employee_id,employee_name,1                         as level,CAST(employee_id AS CHAR) as path,salary,department,manager_idfrom Employeeswhere manager_id is nullunionselect t2.employee_id,t2.employee_name,1 + t1.level,concat(t1.path, ',', t2.employee_id) as path,t2.salary,t2.department,t2.manager_idfrom Employees t2join t1on t2.manager_id = t1.employee_id)
select * from t1

②根据路径 展开主表和子表 将主表employee_id下的所有子员工都展开

select e.employee_id as m_id, e2.employee_id, e2.salaryfrom t1 ejoin t1 e2 on e2.path like concat(e.path, '%')

③根据主employee_id  计算team_size团队人数和budget预算

select m_id, (count(m_id) - 1) as team_size, sum(salary) as budgetfrom t3group by m_id

④将结果进行连接 排序

代码
with recursive t1 as (select employee_id,employee_name,1                         as level,CAST(employee_id AS CHAR) as path,salary,department,manager_idfrom Employeeswhere manager_id is nullunionselect t2.employee_id,t2.employee_name,1 + t1.level,concat(t1.path, ',', t2.employee_id) as path,t2.salary,t2.department,t2.manager_idfrom Employees t2join t1on t2.manager_id = t1.employee_id)
# select * from t1, t3 as (select e.employee_id as m_id, e2.employee_id, e2.salaryfrom t1 ejoin t1 e2 on e2.path like concat(e.path, '%')), t4 as (select m_id, (count(m_id) - 1) as team_size, sum(salary) as budgetfrom t3group by m_id)
select employee_id, employee_name, level, team_size, budget
from t1left join t4 on employee_id = m_id
order by level, budget desc, employee_name;-- 合并
with recursive employee as(select employee_id, employee_name, manager_id, salary, 1 as level, cast(employee_id as char) as pathfrom Employeeswhere manager_id is nullunionselect e2.employee_id,e2.employee_name,e2.manager_id,e2.salary,1 + employee.level,concat(employee.path, ',', e2.employee_id)from Employees e2join employee one2.manager_id = employee.employee_id)
# select * from
, t3 as(select e1.employee_id ,e2.employee_id as emp,e1.employee_name,e1.level,e2.salary from employee e1 left join employee e2 on  e2.path like concat(e1.path,'%')
)
select employee_id,employee_name,level,(count(employee_id)-1) as team_size,sum(salary)'budget'  from t3
group by employee_id, employee_name,level
order by level,budget desc,employee_name
;
总结

①递归查询基本结构

WITH RECURSIVE cte_name (column_list) AS (-- 锚成员(初始查询)SELECT ...UNION [ALL]-- 递归成员(递归查询)SELECT ...
)
SELECT * FROM cte_name;
  • 锚成员:返回初始结果集。
  • 递归成员:通过引用 CTE 自身不断生成新的结果集,直到满足终止条件。

②执行顺序分析

递归查询的执行遵循 迭代模型,步骤如下:

步骤 1:执行锚成员
  • 锚查询首先执行,生成递归的基础结果集(R0)。
步骤 2:执行递归成员
  • 将递归成员应用于上一次迭代的结果集(初始为 R0),生成新的结果集(R1)。
  • 去重处理:如果使用 UNION(而非 UNION ALL),会自动删除重复行。
步骤 3:检查终止条件
  • 如果新生成的结果集(R1)为空,递归终止。
  • 否则,将 R1 作为下一次迭代的输入,重复步骤 2。
步骤 4:合并所有结果
  • 递归终止后,将所有迭代的结果集合并(隐式使用 UNION ALL),返回最终结果。

③ 强转为字符串才可以进行拼接

 cast(employee_id as char)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80344.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工业场景轮式巡检机器人纯视觉识别导航的优势剖析与前景展望

一、引言 1.1 研究背景与意义 在工业 4.0 的大背景下,工业生产的智能化、自动化水平不断提高,对工业场景的巡检工作提出了更高的要求。传统的人工巡检方式不仅效率低下、成本高昂,而且容易受到人为因素的影响,难以满足现代工业生…

《棒球万事通》球类运动有哪些项目·棒球1号位

以棒球运动为例,棒球运动涉及多个核心项目和比赛形式,以下为主要分类: 一、比赛环节 投球(Pitching) 防守方投手向击球员投球,目标是让对方难以击中或制造出局。 击球(Batting) …

第五项修炼:打造学习型组织

最近一直接到的需求,都是公司董事长或总经理都特别推崇《第五项修炼:打造学习型组织》的内容,让各个层级的管理者都持续学习、应用、实践。我不禁开始反思,这背后到底隐藏着什么原因? 随着商业环境的变化和复杂性的增加…

国内AWS CloudFront与S3私有桶集成指南:安全访问静态内容

在现代web应用架构中,将静态内容存储在Amazon S3中并通过CloudFront分发是一种常见且高效的做法。本指南将详细介绍如何创建私有S3桶,配置CloudFront分配,并使用Origin Access Identity (OAI)来确保安全访问。 步骤1:创建S3桶 首先,我们需要创建一个名为"b-static&…

BUUCTF——Nmap

BUUCTF——Nmap 进入靶场 类似于一个nmap的网站 尝试一下功能 没什么用 看看数据包 既然跟IP相关 伪造一个XXF看看 拼接了一下没什么用 果然没这么简单 尝试一下命令注入 构造payload 127.0.0.1 | ls 应该有过滤 加了个\ 直接构造个php木马上传试试 127.0.0.1 | <?…

NPN、PNP三极管的应用

由于电路知识实在是难以拿出手&#xff0c;在面试的时候被问到三极管相关问题&#xff0c;相当地尴尬。在网上简要地学习了相关的理论知识&#xff0c;在这里给出自己的理解。更为基础的原理在这里并不提及。我们面向实际应用学习即可。 我们知道常见的三极管总是硅管&#xff…

系统架构设计师案例分析题——软件架构设计篇

重中之重&#xff0c;本题争取拿下25满分~ 目录 一.核心知识 1.什么是架构风格 2.RUP的9个核心工作流 3.企业应用集成方式 4.软件质量属性 5.SySML系统建模语言9种图 6.云计算架构 7.中间件 8.构件、连接件、软件重用 9.层次型架构的缺点 10.架构开发方法ADM 11.微…

可变参数(Variadic Functions)- 《Go语言实战指南》

Go 语言允许函数接受不定数量的参数&#xff0c;也称“可变参数”。这为构建灵活的函数提供了便利&#xff0c;常用于求和、拼接等操作。 一、语法格式 func 函数名(参数名 ...类型) 返回值类型 {// 函数体 } 可变参数本质上是一个切片&#xff08;slice&#xff09;&#xf…

手机换IP真的有用吗?可以干什么?

在当今数字化时代&#xff0c;网络安全和个人隐私保护日益受到重视。手机作为我们日常生活中不可或缺的工具&#xff0c;其网络活动痕迹往往通过IP地址被记录和追踪。那么&#xff0c;手机换IP真的有用吗&#xff1f;它能为我们带来哪些实际好处&#xff1f;本文将为你一一解答…

Linux517 rsync同步 rsync借xinetd托管 配置yum源回顾

计划测试下定时服务 同步成功 是否为本地YUM源内容太少&#xff1f;考虑网络YUM源 单词拼错了 计划后面再看下 MX安装 参考 计划回顾配置YUM源 配置本地YUM源配置外网YUM源配置仓库YUM源&#xff08;不熟&#xff09; 参考 参考阿里云 配置完毕 本地yum源配置 先备份 再…

第三部分:内容安全(第十六章:网络型攻击防范技术、第十七章:反病毒、第十八章:入侵检测/防御系统(IDS/IPS))

文章目录 第三部分&#xff1a;内容安全第十六章&#xff1a;网络型攻击防范技术网络攻击介绍流量型攻击 --- Flood攻击单包攻击及防御原理扫描窥探攻击畸形报文攻击Smurf攻击Land攻击Fraggle攻击IP欺骗攻击 流量型攻击防御原理DDoS通用攻击防范技术 ---- 首包丢弃TCP类攻击SYN…

c++成员函数返回类对象引用和直接返回类对象的区别

c成员函数返回类对象引用和直接返回类对象的区别 成员函数直接返回类对象&#xff08;返回临时对象&#xff0c;对象拷贝&#xff09; #include <iostream> class MyInt { public:int value;//构造函数explicit MyInt(int v0) : value(v){}//加法操作,返回对象副本&…

阿里巴巴 1688 数据接口开发指南:构建自动化商品详情采集系统

在电商行业数据驱动决策的趋势下&#xff0c;高效获取商品详情数据成为企业洞察市场、优化运营的关键。通过阿里巴巴 1688 数据接口构建自动化商品详情采集系统&#xff0c;能够快速、精准地采集海量商品信息。本文将从开发准备、接口分析、代码实现等方面&#xff0c;详细介绍…

c语言 socket函数

c语言 socket函数 在 C 语言中,socket 函数是网络编程的核心函数之一,用于创建一个网络套接字(socket),它是网络通信的端点。以下是关于 socket 函数的详细介绍: 函数原型 #include <sys/socket.h>int socket(int domain, int type, int protocol);参数说明 domai…

Linux进程通讯和原子性

在Linux系统中&#xff0c;进程间通信&#xff08;IPC&#xff09;和原子性是并发编程中的核心问题。以下是对这些概念的详细分步解释&#xff1a; 一、进程间通信&#xff08;IPC&#xff09;方法 1. 管道&#xff08;Pipe&#xff09; 匿名管道&#xff1a;用于父子进程等有…

Java二叉树题目练习

Java二叉题目练习 相同的树对称二叉树平衡二叉树二叉树的最近公共祖先二叉树的层序遍历二叉树层序遍历 ||二叉树遍历 相同的树 二叉树的题目大多数时候就可以采用递归的方法写 因为二叉树是由根左子树和右子树组成&#xff0c;每一棵左子树和右子树又可以被看成一颗完整的树&am…

【全网首发】解决coze工作流批量上传excel数据文档数据重复的问题

注意&#xff1a;目前方法将基于前一章批量数据库导入的修改&#xff01;&#xff01;&#xff01;&#xff01;请先阅读上篇文章的操作。抄袭注明来源 背景 上一节说的方法可以批量导入文件到数据库&#xff0c;但是无法解决已经上传的条目更新问题。简单来说&#xff0c;不…

dockerdesktop 重新安装

1、卸载 dockerdesktop 卸载时&#xff0c;最后一步删除镜像文件 会卡住 取消 2、在资源管理器中将镜像文件路径改名 如&#xff1a;e:\docker 修改 e:\docker1 3、重新安装wsl wsl --shutdown 以管理员身份运行hy.bat pushd "%~dp0" dir /b %SystemRoot%\servic…

Linux docker常用命令

1、docker服务相关命令 启动docker服务&#xff1a;systemctl start docker 停止docker服务&#xff1a;systemctl stop docker 重启docker服务&#xff1a;systemctl restart docker 查看docker服务状态&#xff1a;systemctl status docker 设置开机启动docker服务&#xff1…

南京邮电大学金工实习答案

一、金工实习的定义 金工实习是机械类专业学生一项重要的实践课程&#xff0c;它绝非仅仅只是理论知识在操作层面的简单验证&#xff0c;而是一个全方位培养学生综合实践能力与职业素养的系统工程。从本质上而言&#xff0c;金工实习是学生走出教室&#xff0c;亲身踏入机械加…