leetcode-Database-184. The highest paid employee in the department rank () + over ()

      
      Original question: https://leetcode-cn.com/problems/department-highest-salary/
      I made the problem-solving record for the database problem of leetcode:
              Problem-solving directory https://blog.csdn.net/weixin_42845682/article/ details / 105196004
      
      

Title description:

      The Employee table contains all employee information, and each employee has its corresponding Id, salary and department Id.

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Henry | 80000  | 2            |
| 3  | Sam   | 60000  | 2            |
| 4  | Max   | 90000  | 1            |
+----+-------+--------+--------------+ 

      The Department table contains information about all departments of the company.

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+ 

      Write a SQL query to find the highest paid employees in each department. For example, according to the table given above, Max has the highest salary in the IT department and Henry has the highest salary in the Sales department.

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| Sales      | Henry    | 80000  |
+------------+----------+--------+ 

      

answer:

The first answer

      At first I felt that this question was very simple, but later I found it a bit difficult. If I were to design the table structure, I would definitely separate the salary table and employee personal information table.

select 
    department Department,
    e1.name Employee,
    tmp.salary Salary  
from employee e1
join (
	select
	    d.name department,
	    d.id id,
	    max(salary) salary 
	from employee e 
	join department d on e.departmentId = d.id 
	group by d.name,d.id 
) tmp on e1.salary = tmp.salary and e1.departmentId = tmp.id 
group by tmp.department, e1.name 

      Although I wrote it and passed the test, I always felt weird when I looked at it.
      The idea is: first find the highest salary of the department, and then use the department and salary to join, employee table (because there may be several departments with the same highest salary, so use the processing funds of the department).
      But how to say, always feel that the employee's name is strange, do not consider the same name? And the title did not say how to show if two people in a department are tied for the highest salary, annoying.

The second answer

      In fact, this sort of segmentation can also be done with row_number ().

select
    dname department,
    ename employee,
    salary 
from(
select
    d.name dname,
    e.name ename,
    e.salary,
    row_number() over(partition by d.name order by salary desc) row_num 
from employee e 
join department d on e.departmentId=d.id 
) tmp
where row_num = 1

      There was an error when submitting. Looked at it and expected the output: if the department has two wages that are as high, then both should be output. That row_number () must not work anymore. . .
      But it's better to change it to dense_rank () or rank ().

select
    dname department,
    ename employee,
    salary 
from(
select
    d.name dname,
    e.name ename,
    e.salary,
    dense_rank() over(partition by d.name order by salary desc) row_num 
from employee e 
join department d on e.departmentId=d.id 
) tmp
where row_num = 1

      To spit: There is no specific explanation on how to deal with these overlapping data; Oracle submission is also really troublesome ... It has been overtime for
      a while:
Insert picture description here
      It seems that I wrote this, and the efficiency is quite high.

      
      
      
      
      

Published 48 original articles · Like 36 · Visits 130,000+

Guess you like

Origin blog.csdn.net/weixin_42845682/article/details/105437193