首页 > 其他分享 >615. 平均工资:部门与公司比较#三种方法

615. 平均工资:部门与公司比较#三种方法

时间:2024-10-31 21:46:25浏览次数:6  
标签:pay 平均工资 amount 三种 date 2017 615 id left

目录

题目和要求

表:Salary

+-------------+------+
| 列名        | 类型 |
+-------------+------+
| id          | int  |
| employee_id | int  |
| amount      | int  |
| pay_date    | date |
+-------------+------+
在 SQL 中,id 是该表的主键列。
该表的每一行表示一个员工一个月的薪资。
employee_id 是来自 Employee 表的外键(reference 列)。
 

表: Employee

+---------------+------+
| 列名          | 类型 |
+---------------+------+
| employee_id   | int  |
| department_id | int  |
+---------------+------+
在 SQL 中,employee_id 是该表的主键列。
该表的每一行表示一个员工所属的部门。
 

找出各个部门员工的平均薪资与公司平均薪资之间的比较结果(更高 / 更低 / 相同)。

以 任意顺序 返回结果表。

结果格式如下所示。

 

示例 1:

输入:
Salary 表:
+----+-------------+--------+------------+
| id | employee_id | amount | pay_date   |
+----+-------------+--------+------------+
| 1  | 1           | 9000   | 2017/03/31 |
| 2  | 2           | 6000   | 2017/03/31 |
| 3  | 3           | 10000  | 2017/03/31 |
| 4  | 1           | 7000   | 2017/02/28 |
| 5  | 2           | 6000   | 2017/02/28 |
| 6  | 3           | 8000   | 2017/02/28 |
+----+-------------+--------+------------+
Employee 表:
+-------------+---------------+
| employee_id | department_id |
+-------------+---------------+
| 1           | 1             |
| 2           | 2             |
| 3           | 2             |
+-------------+---------------+
输出:
+-----------+---------------+------------+
| pay_month | department_id | comparison |
+-----------+---------------+------------+
| 2017-02   | 1             | same       |
| 2017-03   | 1             | higher     |
| 2017-02   | 2             | same       |
| 2017-03   | 2             | lower      |
+-----------+---------------+------------+
解释:
在三月,公司的平均工资是 (9000+6000+10000)/3 = 8333.33...
部门 '1' 的平均薪资是 9000,因为该部门只有一个员工,其员工号为 '1'。因为 9000 > 8333.33,所以比较结果为 'higher'
部门 '2' 的平均薪资是(6000 + 10000)/ 2 = 8000,该平均薪资是员工号 '2' 和 '3' 的薪资的平均值。因为 8000 < 8333.33,比较结果为 'lower'。

根据同样的公式,对于二月份的平均薪资比较,结果为 'same',因为部门 '1' 和 '2' 都与公司的平均薪资相同,即为 7000。

  1. 题目代码
  2. 解题分析图览
  3. 难点分析
  4. 答案代码以及pretty表格解释
  5. 关键总结

1. 题目代码

Create table If Not Exists Salary (id int, employee_id int, amount int, pay_date date);
Create table If Not Exists Employee (employee_id int, department_id int);
Truncate table Salary;
insert into Salary (id, employee_id, amount, pay_date) values ('1', '1', '9000', '2017/03/31');
insert into Salary (id, employee_id, amount, pay_date) values ('2', '2', '6000', '2017/03/31');
insert into Salary (id, employee_id, amount, pay_date) values ('3', '3', '10000', '2017/03/31');
insert into Salary (id, employee_id, amount, pay_date) values ('4', '1', '7000', '2017/02/28');
insert into Salary (id, employee_id, amount, pay_date) values ('5', '2', '6000', '2017/02/28');
insert into Salary (id, employee_id, amount, pay_date) values ('6', '3', '8000', '2017/02/28');
Truncate table Employee;
insert into Employee (employee_id, department_id) values ('1', '1');
insert into Employee (employee_id, department_id) values ('2', '2');
insert into Employee (employee_id, department_id) values ('3', '2');

2. 解题分析图览

方法1:

从 Salary 和 Employee 表中选择数据 计算每月每部门的平均工资 计算公司每月的平均工资 比较每月每部门的平均工资与公司每月平均工资 输出结果

方法2:

从 Salary 和 Employee 表中选择数据 使用窗口函数计算公司每月平均工资 使用窗口函数计算每月每部门的平均工资 比较每月每部门的平均工资与公司每月平均工资 输出结果

方法3:

从 Salary 和 Employee 表中选择数据 根据月份和部门计算平均工资 与公司每月平均工资进行比较 输出结果

3. 难点分析

  • 理解如何使用子查询和窗口函数来计算分组的平均值。
  • 理解如何将部门的平均工资与公司的平均工资进行比较。
  • 理解如何使用 SQL 的 CASE 语句来实现条件判断。

4. 答案代码以及pretty表格解释

-- 方法1 子查询,逐步拆分
select 
    公司各部门.日期 pay_month
     , department_id
     ,case
 when 每月每部门avg工资 >公司每月平均工资 then 'higher'
 when 每月每部门avg工资 <公司每月平均工资 then 'lower'
 else 'same'
end as comparison
from
(
 select department_id,
        avg(amount) as 每月每部门avg工资,
        left(pay_date,7) as 日期
 from salary join employee on salary.employee_id = employee.employee_id
 group by department_id, 日期
) as 公司各部门
join
(
 select avg(amount) as 公司每月平均工资,  left(pay_date,7) as 日期 from salary group by left(pay_date,7)
) as 公司整体
on 公司各部门.日期 = 公司整体.日期;

+---------+-------+
|公司每月平均工资 |日期| select avg(amount) as 公司每月平均工资,  left(pay_date,7) as 日期 from salary group by left(pay_date,7);
+---------+-------+
|8333.3333|2017-03|
|7000.0000|2017-02|
+---------+-------+
+-------------+----------+-------+
|department_id|每月每部门avg工资|日期|select department_id,
+-------------+----------+-------+       avg(amount) as 每月每部门avg工资,
|1            |9000.0000 |2017-03|       left(pay_date,7) as 日期
|1            |7000.0000 |2017-02|from salary join employee on salary.employee_id = employee.employee_id
|2            |8000.0000 |2017-03|group by department_id, 日期;
|2            |7000.0000 |2017-02|
+-------------+----------+-------+
最后日期相等,case判断
+-------------+----------+-------+---------+-------+    when 每月每部门avg工资 >公司每月平均工资 then 'higher'
|department_id|每月每部门avg工资|日期|公司每月平均工资|日期|   when 每月每部门avg工资 <公司每月平均工资 then 'lower'
+-------------+----------+-------+---------+-------+    else 'same'
|1            |9000.0000 |2017-03|8333.3333|2017-03|    higher
|2            |8000.0000 |2017-03|8333.3333|2017-03|    lower
|1            |7000.0000 |2017-02|7000.0000|2017-02|    same
|2            |7000.0000 |2017-02|7000.0000|2017-02|    same
+-------------+----------+-------+---------+-------+
+-------+-------------+----------+
|pay_month|department_id|comparison| 输出结果
+-------+-------------+----------+
|2017-03|1            |higher    |
|2017-03|2            |lower     |
|2017-02|1            |same      |
|2017-02|2            |same      |
+-------+-------------+----------+
;
-- 方法2
SELECT distinct
        left(pay_date,7) pay_month,
        department_id,
       CASE
            WHEN a.每月每部门avg工资 > a.公司每月平均工资 THEN 'higher'
            WHEN a.每月每部门avg工资 < a.公司每月平均工资 THEN 'lower'
            ELSE 'same'
       END AS "comparison"
FROM (
         SELECT
                salary.pay_date,
                department_id,
                AVG(amount) OVER(PARTITION BY left(pay_date,7)) AS 公司每月平均工资,
                AVG(salary.amount) OVER(PARTITION BY employee.department_id, left(pay_date,7)) AS 每月每部门avg工资
         FROM salary
         right join employee
         ON salary.employee_id = employee.employee_id
     ) a;
+----------+-------------+---------+----------+
|pay_date  |department_id|公司每月平均工资 |每月每部门avg工资|
+----------+-------------+---------+----------+
|2017-02-28|1            |7000.0000|7000.0000 |
|2017-03-31|1            |8333.3333|9000.0000 |
|2017-02-28|2            |7000.0000|7000.0000 |
|2017-02-28|2            |7000.0000|7000.0000 |
|2017-03-31|2            |8333.3333|8000.0000 |
|2017-03-31|2            |8333.3333|8000.0000 |
+----------+-------------+---------+----------+
+---------+-------------+----------+
|pay_month|department_id|comparison|
+---------+-------------+----------+
|2017-02  |1            |same      |
|2017-03  |1            |higher    |
|2017-02  |2            |same      |
|2017-03  |2            |lower     |
+---------+-------------+----------+

;
-- 方法3 avg 有一点点长,有局限,看看就行,了解一下
select distinct
    left(pay_date,7) pay_month  ,department_id
,case                                                                                                                                                              -- max也可以
when left(pay_date,7)='2017-01' and avg(amount) over (partition by left(pay_date,7),department_id) > (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-01') then 'higher'-- 1月
when left(pay_date,7)='2017-01' and avg(amount) over (partition by left(pay_date,7),department_id) < (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-01') then 'lower'
when left(pay_date,7)='2017-01' and avg(amount) over (partition by left(pay_date,7),department_id) = (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-01') then 'same'
when left(pay_date,7)='2017-02' and avg(amount) over (partition by left(pay_date,7),department_id) > (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-02') then 'higher'-- 2月
when left(pay_date,7)='2017-02' and avg(amount) over (partition by left(pay_date,7),department_id) < (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-02') then 'lower'
when left(pay_date,7)='2017-02' and avg(amount) over (partition by left(pay_date,7),department_id) = (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-02') then 'same'
when left(pay_date,7)='2017-03' and avg(amount) over (partition by left(pay_date,7),department_id) > (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-03') then 'higher'-- 3月
when left(pay_date,7)='2017-03' and avg(amount) over (partition by left(pay_date,7),department_id) < (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-03') then 'lower'
when left(pay_date,7)='2017-03' and avg(amount) over (partition by left(pay_date,7),department_id) = (select avg(amount) from salary group by left(pay_date,7) having min(left(pay_date,7))='2017-03') then 'same'
    -- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------类推
        -- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    -- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    end comparison
from employee e
left join Salary S on e.employee_id = S.employee_id;

5. 关键总结

  • 掌握 SQL 中的子查询和窗口函数的使用。
  • 理解如何在 SQL 中进行分组计算和条件判断。
  • 熟悉 SQL 的 JOIN 操作,特别是在多表查询中的应用。
  • 理解如何使用 CASE 语句进行条件逻辑处理。

标签:pay,平均工资,amount,三种,date,2017,615,id,left
From: https://blog.csdn.net/weixin_74002941/article/details/143368001

相关文章

  • 二十三种设计模式之命令模式
    目录1.什么是命令模式?2.命令模式的组成3.命令模式的优点4.命令模式的缺点5.使用场景6.实践中的应用7.拓展:命令模式与现代框架8.结语        在软件工程领域,设计模式是解决特定问题的成熟模板。今天,我想和大家分享一种非常实用的行为设计模式——命令......
  • element-ui table中使用type=‘selection‘ 实现禁用,勾选,默认选中不可修改 三种状态显
    element-uitable中使用type=‘selection’实现禁用,勾选,默认选中不可修改三种状态显示问题实现效果   需求1.status=‘CheckOk'时勾选框默认选中但不可修改勾选状态2.status=‘CheckFail'时勾选框禁用3.status=‘'时勾选框可以勾选实现思路采用el-table表格自......
  • SAP-ABAP开发-按钮的三种调用方法
    1、自己创建调用在程序包中右击创建GUI状态,创建使用自己需要的按钮。注意的是,这里调用后会覆盖掉原来的系统的按钮。2、不覆盖系统的情况下加上自己创建的按钮并调用        右键GUI状态点击创建到界面后,点转到---》调整模板 。这里调整模板是指在系统基础上调整,......
  • Linux网络连接三种模式的区别(图解超详细)
    (CentOS安装难点——网络连接方式的理解)参考视频链接为什么选择NAT模式?如上图情景设定:图中三个人在同一个教室网络,可以相互通讯,因为他们三人在同一网段(三者都以192.168.0打头)。1.桥接模式虚拟系统可以和外部系统相互通讯,但是容易造成ip冲突(张三ip:192.168.0.20,他......
  • nginx 根路径同时代理 http ws sse 三种请求
    HTTP(HyperTextTransferProtocol):超文本传输协议,是用于在客户端(通常是web浏览器)和服务器之间传输数据的协议。HTTP是Web的基础,用于请求和传输网页、图像、视频等资源。它采用请求-响应模型,支持多种方法(如GET、POST等),并可通过HTTP/1.1和HTTP/2等版本进行优化,以提高性能和用户体验。......
  • 二叉树的三种遍历方式
    文章目录前言本文章讲解二叉树的三种遍历一、前序遍历1、理解前序遍历2、前序遍历代码二、中序遍历中序遍历代码三、后序遍历后序遍历代码总结前言本文章讲解二叉树的三种遍历前序遍历:先遍历根节点,然后是左节点,最后是右节点-----根左右中序遍历:先遍历左节点,然......
  • vsftp的三种用户详解
    vsfp上有三种用户类型:annoymous匿名用户local_user本地用户virtual_user虚拟用户1、使用匿名用户不需要认证主配置文件中配置:anonymous_enable=YES2、使用本地用户本地用户,就是linux上的系统用户,满足下面两点就可以使用。1、用户的bash是/bin/bash2、主配置文件......
  • 在K8S中,kube-proxy 三种工作模式和原理是什么?
    在Kubernetes(K8s)中,kube-proxy是负责实现Service的网络代理和负载均衡功能的组件。它支持三种不同的工作模式,每种模式的工作原理和特点各不相同。以下是kube-proxy的三种工作模式和原理的详细解释:1.Userspace模式工作原理:kube-proxy监听KubernetesAPI服务器中Service和Endpo......
  • C语言基础入门(小白)三种方法解决幽灵换行符问题
    首先,相信很多读者读到题目都会产生一个共同的疑问:什么是幽灵换行符???    幽灵换行符是指:在C语言中,当用scanf函数时,想要输入几个字符,比如:当输入‘a’之后按下回车键,运行自动结束,而不是等待输入第二个字符,第二个字符就像幽灵般消失了,这是为什么呢??    其实,原因......
  • Day10 函数基础+函数三种定义形式 + 函数的返回值、对象和参数 + 可变长参数
    目录0上节课复习0.1文件是什么0.2操作文件的步骤0.3open0.4指针操作0.5文件的复制1函数基础1.1函数的作用1.2函数的定义形式1.3函数定义的两个阶段2定义函数的三种形式2.1无参函数2.2有参函数2.3空函数3函数的返回值4函数对象5函数参数的应用5.1函数定义分为两个......