Employee with the highest salary in the department (employees with the top three salary in the department)

Table Structure

 employee

department

 

CREATE TABLE `department`  (
  `id` int(0) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `department` VALUES (1, 'IT 部门');
INSERT INTO `department` VALUES (2, '销售部门');

CREATE TABLE `employee`  (
  `id` int(0) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `salary` int(0) NULL DEFAULT NULL,
  `departmentId` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `employee` VALUES (1, 'joe', 70000, 1);
INSERT INTO `employee` VALUES (2, 'jim', 90000, 2);
INSERT INTO `employee` VALUES (3, 'heney', 80000, 2);
INSERT INTO `employee` VALUES (4, 'sam', 70000, 2);
INSERT INTO `employee` VALUES (5, 'kity', 60000, 1);
INSERT INTO `employee` VALUES (6, 'hellen', 68000, 1);
INSERT INTO `employee` VALUES (7, 'hym', 68000, 1);
INSERT INTO `employee` VALUES (8, 'liliy', 72000, 2);

1. If you only query the first name, you can use the simplest method

Query the department Id and salary of the first place in each department

1.查询各个部门第一名的部门Id和薪资
SELECT departmentId,MAX(salary) departmentId FROM employee GROUP BY departmentId;

+--------------+--------------+
| departmentId | departmentId |
+--------------+--------------+
|            1 |        70000 |
|            2 |        90000 |
+--------------+--------------+

2.使用in
SELECT * FROM employee JOIN department on employee.departmentId = department.id 
WHERE #双条件in
  (employee.departmentId,employee.salary) 
in #各部门第一名
	(SELECT departmentId,MAX(salary) departmentId FROM employee GROUP BY departmentId) ;

+----+------+--------+--------------+----+--------------+
| id | name | salary | departmentId | id | name         |
+----+------+--------+--------------+----+--------------+
|  1 | joe  |  70000 |            1 |  1 | IT 部门      |
|  2 | jim  |  90000 |            2 |  2 | 销售部门     |
+----+------+--------+--------------+----+--------------+

2. Query the top three

1. First introduce three functions, the ranking functions rank(), dense_rank(), row_number() in mysql

rank()   is sorted as 1,2,2,4. (One of the tied 2nd places is the third place, so the third place is skipped. The ranks in the figure below are the ranks

name, see the ranks of id=6, 7, and 5 for details)

partition by is equivalent to group by in function sorting

SELECT *,rank() over(partition by departmentId ORDER BY salary desc) ranks FROM employee;

+----+--------+--------+--------------+-------+
| id | name   | salary | departmentId | ranks |
+----+--------+--------+--------------+-------+
|  1 | joe    |  70000 |            1 |     1 |
|  6 | hellen |  68000 |            1 |     2 |
|  7 | hym    |  68000 |            1 |     2 |
|  5 | kity   |  60000 |            1 |     4 |
|  2 | jim    |  90000 |            2 |     1 |
|  3 | heney  |  80000 |            2 |     2 |
|  8 | liliy  |  72000 |            2 |     3 |
|  4 | sam    |  70000 |            2 |     4 |
+----+--------+--------+--------------+-------+

row_number() is sorted as 1,2,3,4 sorted according to the row number

SELECT *,row_number() over(partition by departmentId ORDER BY salary desc) ranks FROM employee;
| id | name   | salary | departmentId | ranks |
+----+--------+--------+--------------+-------+
|  1 | joe    |  70000 |            1 |     1 |
|  6 | hellen |  68000 |            1 |     2 |
|  7 | hym    |  68000 |            1 |     3 |
|  5 | kity   |  60000 |            1 |     4 |
|  2 | jim    |  90000 |            2 |     1 |
|  3 | heney  |  80000 |            2 |     2 |
|  8 | liliy  |  72000 |            2 |     3 |
|  4 | sam    |  70000 |            2 |     4 |

dense_rank() is sorted as 1,2,2,3. (dense means "dense, dense" in English. dense_rank() is that the sorting numbers are continuous and uninterrupted)

SELECT *,dense_rank() over(partition by departmentId ORDER BY salary desc) ranks FROM employee;

| id | name   | salary | departmentId | ranks |
+----+--------+--------+--------------+-------+
|  1 | joe    |  70000 |            1 |     1 |
|  6 | hellen |  68000 |            1 |     2 |
|  7 | hym    |  68000 |            1 |     2 |
|  5 | kity   |  60000 |            1 |     3 |
|  2 | jim    |  90000 |            2 |     1 |
|  3 | heney  |  80000 |            2 |     2 |
|  8 | liliy  |  72000 |            2 |     3 |
|  4 | sam    |  70000 |            2 |     4 |
+----+--------+--------+--------------+-------+

2. Use mysql function to query the top three employees

1.先查询出薪资排名
SELECT *,rank() over(partition by departmentId ORDER BY salary desc) ranks FROM employee;
| id | name   | salary | departmentId | ranks |
+----+--------+--------+--------------+-------+
|  1 | joe    |  70000 |            1 |     1 |
|  6 | hellen |  68000 |            1 |     2 |
|  7 | hym    |  68000 |            1 |     2 |
|  5 | kity   |  60000 |            1 |     4 |
|  2 | jim    |  90000 |            2 |     1 |
|  3 | heney  |  80000 |            2 |     2 |
|  8 | liliy  |  72000 |            2 |     3 |
|  4 | sam    |  70000 |            2 |     4 |

2.再根据已查出的薪资排名,筛选出前三名员工
SELECT * FROM department 
JOIN (
	SELECT *,rank() over(partition by departmentId ORDER BY salary desc) ranks FROM employee) a 
on department.id = a.departmentId WHERE a.ranks <=3 ;

| id | name         | id | name   | salary | departmentId | ranks |
+----+--------------+----+--------+--------+--------------+-------+
|  1 | IT 部门      |  1 | joe    |  70000 |            1 |     1 |
|  1 | IT 部门      |  6 | hellen |  68000 |            1 |     2 |
|  1 | IT 部门      |  7 | hym    |  68000 |            1 |     2 |
|  2 | 销售部门     |  2 | jim    |  90000 |            2 |     1 |
|  2 | 销售部门     |  3 | heney  |  80000 |            2 |     2 |
|  2 | 销售部门     |  8 | liliy  |  72000 |            2 |     3 |

3. Use the traditional method to query the top three 

1.查询出每个薪资数,比其它薪资数高的数量
select * from employee a,employee b where a.departmentId=b.departmentId and a.salary<b.salary;

The meaning of this statement, when translated, is,

There are 3 records for salaries lower than 70000

There are 2 records for salary lower than 68000

. . . . . Why did not get 1 record, because there are two 68000

Salary lower than 60000 has 0 records

select * from employee a JOIN  department ON a.departmentId = department.id 
where (
	select count(1) from employee where a.departmentId=departmentId and a.salary<salary) <3 
order by a.departmentId, a.salary desc;


# where中select count(1) from employee where a.departmentId=departmentId and a.salary<salary) <3

整体查询时a.salary<salary 的意思是,employee的薪资比a中的高(注意:和之前的单独查询是意思不一样哦)
那么

当a中是70000是,count出来薪资比它高的数量是0条,小于3条  满足
当a中是68000是,count出来薪资比它高的数量是1条,小于3条  满足
当a中是60000是,count出来薪资比它高的数量是3条,等于3条  不满足


| id | name   | salary | departmentId | id | name         |
+----+--------+--------+--------------+----+--------------+
|  1 | joe    |  70000 |            1 |  1 | IT 部门      |
|  6 | hellen |  68000 |            1 |  1 | IT 部门      |
|  7 | hym    |  68000 |            1 |  1 | IT 部门      |
|  2 | jim    |  90000 |            2 |  2 | 销售部门     |
|  3 | heney  |  80000 |            2 |  2 | 销售部门     |
|  8 | liliy  |  72000 |            2 |  2 | 销售部门     |


 

 

Guess you like

Origin blog.csdn.net/zs319428/article/details/120880337