1077 Project Staff III
# Write your MySQL query statement below
select project_id, employee_id
from (
select project_id, e.employee_id, rank() over(partition by project_id order by experience_years desc) as rk
from Employee e
join Project p
on e.employee_id = p.employee_id
) tmp
where tmp.rk = 1;
1285 Find the start and end numbers of consecutive intervals
# Write your MySQL query statement below
select min(log_id) as start_id, max(log_id) as end_id
from (
select log_id, log_id - rank() over(order by log_id) as num
from Logs
) t
group by num
train of thought
- First rank each number
- Subtract your own ranking from these numbers. If the result after subtraction is the same, it means that these numbers are consecutive.
- Use the number obtained by subtracting the ranking from logid to perform group by, that is, put all the consecutive numbers in a group, and find the maximum and minimum values of each group.
1596 Most Frequently Ordered Items per Customer
select t.customer_id, t.product_id, p.product_name
from (
select customer_id, product_id,
rank() over(partition by customer_id order by count(product_id) desc) as rk
from Orders
group by customer_id, product_id
) t
join Products p
on t.product_id = p.product_id
where rk = 1
Summarize
- There is a pitfall here, the count will not be grouped according to the partition, so the number of counts must be calculated according to the group by group; secondly, the group by is executed before the window function.
1709 Maximum gap between access dates
select user_id, max(datediff(next_visit, visit_date)) as biggest_window
from (
select user_id,
visit_date,
lead(visit_date, 1, "2021-01-01") over(partition by user_id
order by visit_date) as next_visit
from UserVisits
) tmp
group by user_id
order by user_id;
Summarize
-
Pay attention to the parameters of lead(x,y,z) over(), x represents the column to be searched for, y represents the number of positions to go back, and z represents the default value when x+y cannot find a record.
In this question, lead(visit_date, 1, '2021-01-01') means that what you are looking for is the visit_date column, 1 means visit_date goes back 1 record, and '2021-01-01' means you can't find it when you go back When logging, defaults to '2021-01-01'. The front and back here refer to the front and back after sorting with order by.
1270 Everyone who reports to the CEO of the company
# 写法1
select employee_id from Employees
where manager_id in(
select employee_id from Employees
where manager_id in
(select employee_id from Employees where manager_id=1)
) and employee_id <> 1;
# 写法2
select distinct e1.employee_id
from Employees e1,Employees e2, Employees e3
where e1.manager_id=e2.employee_id and e2.manager_id=e3.employee_id
and e3.manager_id=1 and e1.employee_id !=1
Summarize
- Idea 1: Nested queries
- Idea 2: Combine three tables, this method only
employee_id=manager_id
takes effect when the boss is in charge. - For idea 2, the question at the beginning was not the four-table query. At first, I thought that
employee_id=7
this employee could not be queried, but we can find it if we draw the table. The records in Table 3employee_id=2,manager_id=1
can be queried as follows:
["employee_id", "employee_name", "manager_id", #表1
"employee_id", "employee_name", "manager_id", #表2
"employee_id", "employee_name", "manager_id"] #表3
[7, "Luis", 4,
4, "Daniel", 2,
2, "Bob", 1]
1412 Find students whose grades are in the middle
# 写法1
select distinct e.student_id, student_name
from Exam e
left join Student s
on e.student_id = s.student_id
where e.student_id not in (
select student_id from Exam
where (exam_id, score) in ((select exam_id, max(score) from Exam group by exam_id)
union all (select exam_id, min(score) from Exam group by exam_id))
)
order by student_id;
# 写法2
# 根据成绩升序和降序排序,根据学生id分组,去掉成绩排名中为1的记录
select e.student_id, student_name
from (
select student_id,
rank() over(partition by exam_id order by score desc) max_score_rk,
rank() over(partition by exam_id order by score) min_score_rk
from Exam
) e
left join Student s
on e.student_id = s.student_id
group by e.student_id
having min(e.max_score_rk) <> 1 and min(e.min_score_rk) <> 1
order by e.student_id;
1767 Search for unexecuted task pairs
with recursive t as
(
select task_id, subtasks_count subtask_id from Tasks
union all
select task_id, subtask_id-1 from t where subtask_id > 1
)
select t.task_id, t.subtask_id
from t
left join Executed e
on t.task_id = e.task_id and t.subtask_id = e.subtask_id
where e.subtask_id is null;
Summarize
Directly generate all possible (main task id, subtask id) combinations corresponding to each task through recursive, the following is the usage of recursive.
WITH RECURSIVE cte (n) AS
( select 初始值 from table
union all
select 递归内容 from cte where (终止条件)
)