SQL buckle practice (6)

Table of contents

1. All employees with the top three salaries in the department (185)

Solution 1 (dense_rank() window function)

Solution 2 (custom function)

 2. Delete duplicate email addresses(196)

Solution 1

Solution 2 (official analysis)

3. Rising temperature(197)

Solution 1 (DATEDIFF())

Solution 2 (TIMESTAMPDIFF())

Solution 3 (ADDDATE() button)


1. All employees with the top three salaries in the department (185)

surface: Employee

+--------------+---------+ 
| Column Name | Type | 
+-------------+-- -------+ 
| id | int | 
| 
name | varchar | 
| salary | int | 
| departmentId | ---+ 
Id is the primary key column of the table. 
departmentId is a foreign key to the ID in the Department table. 
Each row of this table represents an employee's ID, name, and salary. It also contains the ID of their department.

surface: Department

+-------------+---------+ 
| Column Name | Type | 
+-------------+---- -----+ 
| id | int | 
| name | varchar | 
+-------------+---------+ 
Id is the primary key column of the table. 
Each row of this table represents a department ID and a department name.

Company executives are interested in who makes the most money in each department of the company. A high earner in a department   is when an employee's salary  ranks in the top three among different  salaries  in that department  .

Write a SQL query to find  the high paid employees in each department  .

Return the result table in  any order  .

Solution 1 (dense_rank() window function)

dense_rank() sorting rules 1 2 3 3 4

rank() 1 2  3 3 5

partition by partition according to a field

# Write your MySQL query statement below
select  Department, Employee, Salary 
from (select d.name Department,e.name Employee,e.salary Salary ,dense_rank() over(partition by d.name order by e.salary desc) no from employee e join department d
on e.departmentId=d.id) temp
where temp.no<=3

Solution 2 (custom function)

Until now, I have only become a little proficient in the usage of this custom function. The emergence of this custom function can make SQL more flexible.

CASE 
         WHEN @pre = DepartmentId THEN @rank:= @rank + 1
         WHEN @pre := DepartmentId THEN @rank:= 1
END AS 'RANK'

This means, if @pre is equal to the current DepartmentId, add one to @rank, otherwise update the value of @pre and @rank=1.

The value of this @rank is named the RANK field. The key to sorting with this is that the from table needs to be in order.

SELECT dep.Name Department, emp.Name Employee, emp.Salary
FROM (## 自定义变量RANK, 查找出 每个部门工资前三的排名
        SELECT te.DepartmentId, te.Salary,
               CASE 
                    WHEN @pre = DepartmentId THEN @rank:= @rank + 1
                    WHEN @pre := DepartmentId THEN @rank:= 1
               END AS 'RANK'
        FROM (SELECT @pre:=null, @rank:=0)tt,
             (## (部门,薪水)去重,根据 部门(升),薪水(降) 排序
                 SELECT DepartmentId,Salary
                 FROM Employee
                 GROUP BY DepartmentId,Salary
                 ORDER BY DepartmentId,Salary DESC
             )te
       )t
INNER JOIN Department dep ON t.DepartmentId = dep.Id
INNER JOIN Employee emp ON t.DepartmentId = emp.DepartmentId and t.Salary = emp.Salary and t.RANK <= 3
ORDER BY t.DepartmentId, t.Salary DESC ## t 结果集已有序,根据该集合排序

 2. Delete duplicate email addresses(196)

surface: Person

+-------------+---------+ 
| Column Name | Type | 
+-------------+---- -----+ 
| id | int | 
| email | varchar | 
+-------------+---------+ 
id is the primary key column of the table. 
Each row of this table contains an email. Emails will not contain capital letters.

Write a SQL  delete statement to  delete  all duplicate emails, keeping only one unique email with the smallest id.

Return the result table in  any order  . ( Note : You only need to write the delete statement, and the remaining results will be queried automatically)

Solution 1

First of all, think backwards to find out the unsatisfactory, which can be easily found according to the grouping

DELETE from Person
WHERE id NOT IN #不在满足条件内的肯定就是不满足的,直接删除
(
    SELECT ID #先把满足条件的找出来
    From
    (
     SELECT  MIN(id) as ID
     From Person
     Group by Email
    )t
)

Solution 2 (official analysis)

# Write your MySQL query statement below
DELETE p1 FROM Person p1,
    Person p2
WHERE
    p1.Email = p2.Email AND p1.Id > p2.Id

3. Rising temperature(197)

surface: Weather

+---------------+---------+ 
| Column Name | Type | 
+---------------+ ---------+ 
| id | int | 
| 
recordDate | date | 
| temperature | -+ 
id is the primary key of this table 
which contains temperature information for a specific date

Write a SQL query to find all dates that have a higher temperature than the previous (yesterday's) date  id .

The returned results  do not require order  .

Example 1:

输入:
Weather 表:
+----+------------+-------------+ 
| id | recordDate | Temperature | 
+----+---- --------+-------------+ 
| 1 | 2015-01-01 | 10 | 
| 2 | 2015-01-02 | 25 | 
| 3 | 2015- 01-03 | 20 | 
| 4 | 2015-01-04 | 30 | 
+----+------------+-------------+ Output: 
+----+ 
| id | 
+----+ 
| 2 | 
| 4 | 
+----+ Explanation: 
The temperature on 2015-01-02 is higher than the previous day (10 -> 25) 
2015- 01-04 the temperature was higher than the previous day (20 -> 30)

Solution 1 (DATEDIFF())

DATEDIFF function, which can calculate the date difference between the two

DATEDIFF('2007-12-31','2007-12-30');   # 1
DATEDIFF('2010-12-30','2010-12-31');   # -1

# Write your MySQL query statement below  

select a.ID
from weather as a cross join weather as b 
     on datediff(a.recordDate, b.recordDate) = 1
where a.temperature > b.temperature;

Solution 2 (TIMESTAMPDIFF())

What TIMESTAMPDIFF can do, it can calculate the difference in days, hours, minutes and seconds, which is much more flexible than the datediff function. The format is that the time is small before, and the time is big behind. Calculate the difference in days

select a.ID
from weather as a cross join weather as b 
     on timestampdiff(day,a.recordDate, b.recordDate) = -1
where a.temperature > b.temperature;

Solution 3 (ADDDATE() button )

select a.id 
    from weather a join weather b 
    on (a.recorddate = adddate(b.recorddate,INTERVAL 1 day))
where a.temperature > b.temperature

 

Guess you like

Origin blog.csdn.net/weixin_53011574/article/details/131595834