【SQL篇】面试篇之子查询
1303 求团队人数
# 写法1
# Write your MySQL query statement below
select employee_id, count(*) over(partition by team_id) as team_size
from Employee
# 写法2
# Write your MySQL query statement below
select employee_id, team_size
from Employee e
join (
select team_id, count(*) as team_size
from Employee
group by team_id
) tmp
on e.team_id = tmp.team_id
总结
- 考察子查询
- 学会使用窗口函数
512 游戏玩法分析 II
# 写法1
# Write your MySQL query statement below
select player_id, device_id
from (
select player_id, device_id,
rank() over(partition by player_id order by event_date) as rk
from Activity
) tmp
where tmp.rk = 1
# 写法2
# Write your MySQL query statement below
select player_id, device_id
from Activity
where (player_id, event_date) in (
select player_id, min(event_date)
from Activity
group by player_id
);
184 部门工资最高的员工
# 写法1
select d.name as Department, e.name as Employee, e.salary as salary
from Employee e
join Department d
on e.departmentId = d.id
where (e.departmentId, salary) in (
select departmentId, max(salary)
from Employee
group by departmentId
);
# 写法2 rank()
select d.name as Department, e.name as Employee, salary
from (
select *,
rank() over(partition by departmentId order by salary desc) as rk
from Employee
) e, Department d
where e.departmentId = d.id and e.rk = 1;
# 写法3 dense_rank()
select d.name as Department, e.name as Employee, salary
from (
select *,
dense_rank() over(partition by departmentId order by salary desc) as rk
from Employee
) e, Department d
where e.departmentId = d.id and e.rk = 1;
总结
row_number, rank(), dense_rank()
的区别
rank()
排序相同时会重复,总数不变,即会出现1、1、3
这样的排序结果;dense_rank()
排序相同时会重复,总数会减少,即会出现1、1、2
这样的排序结果;row_number()
排序相同时不会重复,会根据顺序排序。
- 注意点
- row_number函数得到的列别名可用于order by 排序,因为order by执行在select之后。
- where, group by, having都不可引用该列,因为这些语句执行在select之前,此时函数尚未计算出值。
1549 每件商品的最新订单
- 1549题
# 写法1
# Write your MySQL query statement below
select p.product_name, p.product_id, order_id, order_date
from Products p
join Orders o
on p.product_id = o.product_id
where (p.product_id, order_date) in (
select product_id, max(order_date)
from Orders
group by product_id
)
order by product_name, product_id, order_id
# 写法2
# Write your MySQL query statement below
select p.product_name, p.product_id, tmp.order_id, tmp.order_date
from (
select *, dense_rank() over(partition by product_id order by order_date desc) as rk
from Orders
) tmp, Products p
where tmp.product_id = p.product_id and rk = 1
order by product_name, product_id, order_id
总结
- 该题与顾客表无关,我们只需要订单表和商品表就可。
- 注意dense_rank()和row_number()的区别,不要用错。
1532 最近的三笔订单
- 1532题
# 写法1
# Write your MySQL query statement below
select c.name as customer_name, c.customer_id, o.order_id, o.order_date
from (
select *, rank() over(partition by customer_id order by order_date desc) as rk
from Orders
) o, Customers c
where o.customer_id = c.customer_id and rk <= 3
order by customer_name, customer_id, order_date desc;
1831 每天的最大交易
# 写法1
# Write your MySQL query statement below
select transaction_id
from Transactions
where (day(day), amount) in (
select day(day) as t, max(amount) as mx
from Transactions
group by t
)
order by transaction_id;
# 写法2
select transaction_id
from (
select transaction_id, rank() over(partition by day(day) order by amount desc) as rk
from Transactions t
) tmp
where rk = 1
order by transaction_id;
参考
- row_number()等函数详解