【数据库】取前三

题设

有两表如下:
Employee 表:记录员工的 id,姓名,工资和部门id

+----+------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+------+--------+--------------+
|  1 ||  85900 |            1 |
|  2 ||  85900 |            2 |
|  3 ||  90000 |            2 |
|  4 ||  89000 |            1 |
|  5 ||   6767 |            1 |
|  6 ||   1234 |            1 |
|  7 ||   3456 |            1 |
|  8 ||  89000 |            1 |
+----+------+--------+--------------+

Department 表:记录部门id 和对应部门名称

+----+-------+
| Id | Name  |
+----+-------+
|  1 | 部门1 |
|  2 | 部门2 |
+----+-------+

要求
取各部门工资前三的员工显示
下分两种情况:

  1. 工资排名前三
    即日常中常见的排名规则,例 x 工资 100,y 和 z 工资 200,m 和 n 工资 300,则前三为 m,n,y,z。
  2. 工资前三高
    只按工资高低排序,同一阶级工资的人数不影响后面的排名,例 x 工资 100,y 和 z 工资 200,m 和 n 工资 300,则第一名为 m 和 n,第二名为 y 和 z,第三名为 x,前三为 m,n,y,z,x。
工资排名前三

思路1
某人工资排名前三,等价于工资比其高的人小于三个
sql 语句

select d.Name as Department,
    e.Name as Employee, 
    e.Salary
from Employee e
join Department d on e.DepartmentId = d.Id
where e.Id in(
    select e1.id from Employee e1 
	left join Employee e2
    on e1.DepartmentId = e2.DepartmentId and e1.Salary < e2.Salary
    group by e1.id
    having count(e1.id) < 3
)
order by d.Name, Salary desc;

简化:

select d.Name as Department,
    e.Name as Employee, 
    e.Salary
from Employee e
join Department d on e.DepartmentId = d.Id
where 3 > (
    select count(e1.Id) from Employee e1 
    where e1.DepartmentId = e.DepartmentId and e1.Salary > e.Salary
)
order by d.Name, Salary desc;

思路2
某人工资排名前三,等价于比其工资的工资(包括重复)小于三个
sql 语句

select d.Name as Department,
    e.Name as Employee, 
    e.Salary
from Employee e
join Department d on e.DepartmentId = d.Id
where 3 > (
	select count(e1.Salary)
    from Employee e1
    where e1.DepartmentID = e.DepartmentId and e1.Salary > e.Salary
)
order by d.Name, Salary desc;

运行结果

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| 部门1      ||  89000 |
| 部门1      ||  89000 |
| 部门1      ||  85900 |
| 部门2      ||  90000 |
| 部门2      ||  85900 |
+------------+----------+--------+
工资前三高

某人工资前三高,等价于比其工资数额高的工资数额小于三个
sql 语句

select d.Name as Department,
    e.Name as Employee, 
    e.Salary
from Employee e
join Department d on e.DepartmentId = d.Id
where 3 > (
	select count(distinct e1.Salary)
    from Employee e1
    where e1.DepartmentID = e.DepartmentId and e1.Salary > e.Salary
)
order by d.Name, Salary desc;

也可写为:

select d.Name as Department,
    e.Name as Employee, 
    e.Salary
from Employee e
join Department d on e.DepartmentId = d.Id
where e.Id in(
    select e1.id from Employee e1 
	left join Employee e2
    on e1.DepartmentId = e2.DepartmentId and e1.Salary < e2.Salary
    group by e1.id
    having count(distinct e2.Salary) < 3
)
order by e.DepartmentId, e.Salary DESC;

运行结果

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| 部门1      ||  89000 |
| 部门1      ||  89000 |
| 部门1      ||  85900 |
| 部门1      ||   6767 |
| 部门2      ||  90000 |
| 部门2      ||  85900 |
+------------+----------+--------+
题外话

MySQL 中sql语句的执行顺序

  1. from
  2. on
  3. join
  4. where
  5. group by
  6. cube | rollup
  7. having
  8. select
  9. distinct
  10. order by
  11. limit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值