💡
Các câu hỏi trong phần này không quá khó về mặt sử dụng các kỹ thuật SQL, nhưng phức tạp về mặt tư duy cấu trúc dữ liệu của bảng để đưa ra hướng giải hợp lý.
Các kiến thức cần thiết để giải quyết list câu hỏi này
- Cần phải nắm rõ các kiến thức cơ bản của SQL sử dụng trong các phần trước. Như LeetCode EZ - SQL50 - Basic Joins và LeetCode EZ - SQL50 - Basic Aggregate Functions.
- Sử dụng được thành thạo các
WINDOW FUNCTIONS
- Hiểu cách
Subquery
hoạt động và thực hiệnJOIN
các bảng hợp lý - Làm quen với
AGGREGATE FUNCTIONS
để tạo mảng (array) thay vìcount
,sum
hayavg
như thông thường.
Câu 1978. Employees Whose Manager Left the Company
Table: Employees
+-------------+----------+
| Column Name | Type |
+-------------+----------+
| employee_id | int |
| name | varchar |
| manager_id | int |
| salary | int |
+-------------+----------+
Find the IDs of the employees whose salary is strictly less than $30000 and whose manager left the company. When a manager leaves the company, their information is deleted from the Employees table, but the reports still have their manager_id set to the manager that left.
Đáp án
select
tmp.employee_id
from
Employees e
right join (
select
employee_id,
manager_id
from
Employees
where
salary < 30000
and manager_id is not null
) tmp on e.employee_id = tmp.manager_id
where
e.employee_id is null
order by
1 asc
Câu 626. Exchange Seats
Table: Seat
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| student | varchar |
+-------------+---------+
Write a solution to swap the seat id of every two consecutive students. If the number of students is odd, the id of the last student is not swapped.
Đáp án
select
case
when id % 2 = 0 then id -1
when id % 2 != 0
and id != mid then id + 1
else id
end as id,
student
from
Seat
cross join (select max(id) mid from Seat) as tmp
order by 1
Câu 1341. Movie Rating
Table: Movies
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| movie_id | int |
| title | varchar |
+---------------+---------+
Table: Users
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| user_id | int |
| name | varchar |
+---------------+---------+
Table: MovieRating
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| movie_id | int |
| user_id | int |
| rating | int |
| created_at | date |
+---------------+---------+
Write a solution to:
- Find the name of the user who has rated the greatest number of movies. In case of a tie, return the lexicographically smaller user name.
- Find the movie name with the highest average rating in February 2020. In case of a tie, return the lexicographically smaller movie name.
Đáp án
select
results
from
(
(
select
name as results,
'name' as name
from
Users u
join (
select
user_id,
count(rating) cnt_rating
from
MovieRating
group by
1
) tmp on tmp.user_id = u.user_id
order by
cnt_rating desc,
u.name asc
limit
1
)
union
(
select
title as results,
'title' as name
from
Movies m
join (
select
movie_id,
avg(rating) as avg_rating
from
MovieRating
where
date_trunc('month', created_at) = '2020-02-01' :: date
group by
1
) tmp on m.movie_id = tmp.movie_id
order by
avg_rating desc,
m.title asc
limit
1
)
)
Câu 1321. Restaurant Growth
Table: Customer
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| customer_id | int |
| name | varchar |
| visited_on | date |
| amount | int |
+---------------+---------+
Compute the moving average of how much the customer paid in a seven days window (i.e., current day + 6 days before). average_amount should be rounded to two decimal places.
Đáp án
select
visited_on,
amount,
average_amount
from
(
select
visited_on,
round(
sum(amount) OVER (ORDER BY visited_on asc ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), 2) amount,
round(
avg(amount) OVER (ORDER BY visited_on asc ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), 2) average_amount,
rank() over (order by visited_on asc) as rank
from
(
select
visited_on,
sum(amount) as amount
from
Customer
group by 1
order by 1 asc
)
) tmp
where
rank >= 7
Câu 602. Friend Requests II: Who Has the Most Friends
Table: RequestAccepted
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| requester_id | int |
| accepter_id | int |
| accept_date | date |
+----------------+---------+
Write a solution to find the people who have the most friends and the most friends number.
Đáp án
select
requester_id id,
count(distinct accepter_id) num
from
(
(
select
accepter_id as requester_id,
requester_id as accepter_id
from
RequestAccepted
)
union
(
select
requester_id,
accepter_id
from
RequestAccepted
)
) tmp
group by 1 order by 2 desc limit 1
Câu 585. Investments in 2016
Table: Insurance
+-------------+-------+
| Column Name | Type |
+-------------+-------+
| pid | int |
| tiv_2015 | float |
| tiv_2016 | float |
| lat | float |
| lon | float |
+-------------+-------+
Write a solution to report the sum of all total investment values in 2016 tiv_2016, for all policyholders who:
- have the same tiv_2015 value as one or more other policyholders,
- and are not located in the same city as any other policyholder (i.e., the (lat, lon) attribute pairs must be unique).
Đáp án
with valid as (
select
tmp1.pid
from
(
select
unnest(pids) pid
from
(
select
tiv_2015,
array_agg(pid) pids
from
Insurance
group by 1
having count(pid) > 1
)
) tmp1
join (
select
unnest(pids) pid
from
(
select
array_agg(pid) pids,
lat,
lon
from
Insurance
group by 2, 3
having count(pid) = 1
) tmp
) tmp2 on tmp1.pid = tmp2.pid
)
select
round(sum(i.tiv_2016) :: numeric, 2) tiv_2016
from
Insurance i
join valid v on v.pid = i.pid
Câu 185. Department Top Three Salaries
Table: Employee
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| id | int |
| name | varchar |
| salary | int |
| departmentId | int |
+--------------+---------+
Table: Department
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
+-------------+---------+
A company's executives are interested in seeing who earns the most money in each of the company's departments. A high earner in a department is an employee who has a salary in the top three unique salaries for that department.
Write a solution to find the employees who are high earners in each of the departments.
Đáp án
with j as (
select
d.name as Department, e.name as Employee, e.salary as Salary
from
Employee e
join Department d on e.departmentId = d.id
order by 1, 3 desc
)
select
j.*
from j
join (
select Department, Salary
from
(
select *, rank() over(partition by Department order by Salary desc)
from
(
select Department, Salary
from j
group by 1,2 order by 1,2 desc
) tmp
)
where rank <= 3
) tmp on j.Department = tmp.Department and j.Salary = tmp.Salary