美文网首页数据库相关
MySQL 一表分组查询max

MySQL 一表分组查询max

作者: Kaidi_G | 来源:发表于2018-06-20 18:40 被阅读1次

一个很常见的较为复杂的查询,在同一张表里求某个分组下某个属性最高的前N位记录,主要有两种方法实现,这里详细说明一下。

假设一张表记录了员工,薪水和部门Id

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Henry | 80000  | 2            |
| 3  | Sam   | 60000  | 2            |
| 4  | Max   | 90000  | 1            |
+----+-------+--------+--------------+

另一张表记录了部门ID和名字

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

我们希望求每个部门里薪水最高的员工和信息。

方法一 实用,简单,适用于只求每组最高/最低记录的情况


思路为,用employee表A与自己(B)进行联合查询,
联合条件为A.departmentid = B.departmentid,意即将同一部门的人进行全对比,
选取所有对比中的MAX(salary),就自然会得到同一部门里面最高salary的记录
这样就可以不用group by 的取得分组里的最大记录了

select * from employee a 
where a.salary = (
select max(salary) from employee b
    where b.departmentId = a.departmentId
)

这个时候我们就可以在外层再联合department表将部门id替换为部门名字

select d.name as department, t.name as employee, t.salary
from department d,(
    select * from employee a 
    where a.salary = (
        select max(b.salary) 
        from employee b
        where b.departmentId = a.departmentId
    )
)t
where d.id = t.departmentid

不过这个嵌套结构也可以稍微进行改进,就是我们先把部门表和其中一个employee表交了,得到带部门名称的一张表,再与原始employee联合查询

select d.name as Department, a.name as Employee, a.Salary
from employee a 
join department d 
on d.id = a.departmentid
where a.salary = (
    select max(b.salary)
    from employee b
    where b.departmentId=a.departmentId)

方法二 暴力统计,可以计算每组前N位的记录,但不能只输出最高记录,意即N必须大于1


把employee表和自己左交,联合条件依然是a.departmentId = b.departmentId,以及,a.salary < b.salary.
这时会产生一张大表,记录了所有同部门之间的比较,
也就是说,对于某个部门最高薪水的那个人,他的记录会出现1次(因为左交一定会显示左表全部行哪怕没有匹配),表右部分为NULL,
而薪水最低的那个人,他的记录会出现n-1次,意即,在部门里其他人都比他工资高。

得到这张表之后,只需要按a的部门分组统计count有几条记录。
最高薪水的人应该只有一条记录,
第二高的人count也只有一条记录(只有第一名比他薪水高),
第三名count应该有两条记录(第一名和第二名)....

但是注意,此方法无法区分第一名和第二名(都是一条记录),所以无法只选出第一名(但是可以根据salary的具体数值在输出表进行排序)

select * from employee a
join employee b
on a.departmentId = b.departmentId
and a.salary < b.salary
group by a.Id,a.departmentId
having count(*)<3

相关文章

  • MySQL 一表分组查询max

    一个很常见的较为复杂的查询,在同一张表里求某个分组下某个属性最高的前N位记录,主要有两种方法实现,这里详细说明一下...

  • 数据库高级查询2

    分组查询(group by) 分组查询: 1.查询每个部门的最高工资 select deptno,max(sal)...

  • MySQL——分组函数、distinct、分组查询、连接查询、子

    MySQL——分组函数、distinct、分组查询、连接查询、子查询 一、分组函数(聚合函数)1、 会自动忽略空值...

  • 05-Mysql数据库02

    mysql数据查询 条件查询 模糊查询 范围查询 判断空 排序 聚合函数 分组 分组要和聚合一起用 分页 连接查询...

  • MySQL 自定义起始日,按日、周、月、年分组查询

    MySQL 自定义起始日,按周分组查询 先来看看简单的按日(天)、月、年分组查询 用到的 mysql 内置方法D...

  • MYSQL分组查询

    groub by 分组的含义: 将查询结果按照1个或多个字段进行分组,字段值相同的为一组 可用于单个字段分组,也可...

  • MySql查询-分组

    group by group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组 group b...

  • mysql分组查询

    只使用group by u.letter,只会显示每组的第一条数据

  • mysql分组查询

    进阶5:分组查询 /*语法: select 查询列表from 表【where 筛选条件】group by 分组的字...

  • MySQL分组查询

    根据性别进行学生表的分组 查询每个不猛编号和部门的工资和

网友评论

    本文标题:MySQL 一表分组查询max

    本文链接:https://www.haomeiwen.com/subject/ckbxyftx.html